저도 모릅니다. 이거 연결하면 텔레그램에 있는 메세지를 전부 matrix로 받아볼 수 있는 것만 알아요. 움직이는 거 보니까 일종의 외부 접속 어플리케이션으로 인식하는 거 같더라고요.
일단 matrix-telegram 사이를 연결해주는 브릿지 서버(깃헙)를 올리던가 남이 만들어둔 브릿지 봇을 써야합니다. 남이 만들어둔 브릿지 봇은 여기서 참고(링크)
저는 브릿지 서버를 올리는 방법을 기록할 거예요. 공식 가이드(설치, 도커)참고하면 되는데 이거 진짜 설정 복잡합니다.
이게 깃헙에 올라가있는 예시 링크인데 길이 보세요. (링크)
차근차근 갑시다. 도커 컴포즈 기준이에요.
homeserver:
address: [https://실제 서비스 주소]
domain: [핸들 주소]
verify_ssl: true
http_retry_cont: 4
status_endpoint: [비워두세요]
message_send_checkpoint_endpoint: [비워두세요]
async_media: false
대부분의 값은 디폴트 값으로 뒀으니 주석 참고하세요.
appservice:
address: [http://도커로 올린 브릿지 서버 이름:29317]
tls_cert: false
tls_key: false
hostname: 0.0.0.0
port: 29317
max_body_size: 1
public:
enabled: false
prefix: /public
external: [http://실제 서비스 주소/public]
provisioning:
enabled: true
prefix: /_matrix/provision
shared_secret: [자동생성]
id: telegram
bot_username: telegrambot
bot_displayname: Telegram bridge bot
bot_avatar: mxc://maunium.net/tJCRmUyJDsgRNgqhOgoiHWbX
ephemeral_events: true
as_token: [자동생성]
hs_token: [자동생성]
metrics, manhole 설정은 건드리지 않았습니다.
bridge:
...
double_puppet_server_map:
[핸들 주소]: [https://실제 서비스 주소]
double_puppet_allow_discovery: false
login_shared_secret_map:
[핸들 주소]: as_token:[자유 랜덤 문자열]
double puppeting은 주석에도 설명이 있지만, 텔레그램에서 올라온 내 글과 매트릭스에서 올라온 내 글을 모두 볼 수 있게 해주는 거예요. 그 뒷부분도 저는 기존 예시대로 유지했습니다.
그 다음으로 중요한 부분은 bridge안에 있는 encryption 설정입니다.
...
permissions:
[유저/서버]: [권한]
유저/서버 '*' : 모든 매트릭스 유저 '도메인': 특정 서버의 모든 유저 '유저 핸들': 사용할 수 있는 유저
권한 'relaybot': 커맨드는 사용할 수 없고 브릿지 연결로만 사용할 수 있는 권한 'user': relaybot 권한에 브릿지를 만들 수 있는 접속 명령 사용 가능 'puppeting': user 권한에 텔레그램 계정에 로그인 할 수 있는 권한 'full': 브릿지 봇의 모든 권한 사용 가능. matrix 로그인 가능 'admin': 브릿지 봇의 모든 권한 및 관리 명령어 사용 가능
써두긴 했는데 정확한 건 설정 예시 참조해주세요.
relaybot:
...
whitelist:
- [유저명]
봇 명령을 사용할 수 있는 유저 목록
telegram:
api_id: [https://my.telegram.org/apps에서 얻은 api_id]
api_hash: [https://my.telegram.org/apps에서 얻은 api_hash]
bot_token: [https://t.me/BotFather를 통해 얻은 봇 토큰]
...
device_info:
device_model: [도커 컴포즈에서 설정한 브릿지 서버 이름]
* 경고 이 바로 아래 있는
server:
enabled: false
는 반드시 false로 유지해야합니다. 한 번이라도 true로 바꾸면 데이터베이스를 갈아엎어야해요. 저는 데이터베이스 필요없다는 걸 깨닫고 해제해서 해결함.
여기까지 진행했으면 브릿지 서버에는 큰 문제가 없을 거예요.
그 다음은 homeserver.yaml
입니다.
app_service_config_files:
- /data/matrix-telegram/registration.yaml
- /data/matrix-telegram/doublepuppet.yaml
일단 여기에 이렇게 설정을 추가해주고, registration.yaml
은 자동으로 생기는 거니 건드리지 않으면 됩니다. doublepuppet.yaml
은 이 페이지를 참고해주세요.
id: doublepuppet
url:
as_token: [아래 설명]
hs_token: [안 쓰이는 거니까 아무거나 넣으세요]
sender_localpart: [적당히 아무거나]
rate_limited: false
namespaces:
users:
- regex: '@.*:내\.도메인'
exclusive: false
as_token은 bridge 설정 안에 있는
login_shared_secret_map:
[핸들 주소]: as_token:[자유 랜덤 문자열]
의 as_token 뒤의 문자열을 넣으면 됩니다.
정보가 부족한 부분이 있거나 잘못된 부분이 있으면 mastodon로 연락주세요.
공식 가이드대로 하면 됩니다. ...만, 주의사항.
공식 가이드에서 제공하는 설정에는 함정이 있습니다.
localpart_template: "{{ user.username }}
이 설정은 마스토돈 유저의 핸들을 그대로 활용하여 로그인하게 하는 방법입니다. 여기서 문제가 생기는 게 무어냐, oidc를 활용한 가입을 열어두었을 경우 같은 아이디가 있으면 자동으로 id 뒤에 숫자가 붙어 중복 가입을 시켜버립니다.
반대로 oidc를 활용한 가입을 닫아두었을 경우 로그인이 불가합니다. allow_existing_users
옵션을 켜두었을 경우 같은 아이디를 가진 유저로 바로 로그인이 됩니다. 즉, 다른 유저로 인증 없이 로그인이 가능합니다.
그래서 localpart_template
를 없애보았는데 이번엔 비밀번호로 이미 가입한 계정에 연동하는 게 안 되더라고요. 덕분에 비밀번호 가입과 oidc를 동시 연동하겠다는 꿈이 깨졌습니다... ㅇ_ㅠ...
만져보니 db를 직접 건드리거나 이리저리 꼼수를 쓰면 어떻게 가능할 것 같긴 한데 추천하진 않습니다.
결론: 비밀번호 가입과 마스토돈 가입을 동시에 열어두면 로그인이 꼬인다.
참고로 기본 메뉴얼에도 있는 정보지만 enable_registration
를 켜두면 비밀번호 가입과 별도로 해당 oidc로 회원가입 여부를 결정할 수 있습니다.
matrix 클라이언트에서 보면 음성, 화상 채팅 기능이 있다. 그런데 서버를 올리고 보니 기능이 없어서 그게 안 되더라. 알아보니 VoIP를 통해 통신을 해야하고 그걸 해주는 TURN 서버를 붙여야한다고...
해서, 붙여봤습니다.
TURN 서버는 coturn으로 올렸습니다. 공식 가이드에 따르면 apt로 설치해서 돌리는 건데 저는 굳이 docker로 올렸어요. 다행히 coturn 공식에서 제공하는 docker compose 문서가 친절해서 금방 설치할 수 있었습니다.
위 docker-compose.yml 문서와 관련한 주의점.
마지막으로 turnserver.conf는 coturn에서 제공하는 공식 예시와 matrix에서 제공하는 안내 문서가 있습니다. 저는 cotrun에서 제공하는 공식 예시를 보고 작성했어요.
listening-port=3478
tls-listening-port=5349
여기까진 기본 설정입니다.
listening-ip=
external-ip=[서버 아이피]
listening-ip는 비워두면 모든 ip에서 수신합니다. external-ip는 서버 외부 ip예요. 이쪽으로 오면 된다고 알려주는 겁니다.
static-auth-secret=[비밀 키]
server-name=[TURN 서버명]
realm=[TURN 서버 도메인]
여기는 써있는대로.
cert=[cert.pem 경로]
pkey=[private key 경로]
이건 openssl로 만들었어요.
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
syslog
simple-log
로그 설정. 저는 file에다 지정했는데 바꾸려고요.
나머지는 matrix 문서에서 하라는 대로 하면 됩니다. 저는 coturn 문서 보고 하는 바람에 오히려 헷갈린 게 많긴 했어요. 워낙 옵션이 많아서...
turn_uris: [ "turn:[TURN 서버 도메인]?transport=udp", "turn:[TURN 서버 도메인]?transport=tcp" ]
turn_shared_secret: "turnserver.conf에서 static-auth-secret에 넣은 비밀 키"
turn_user_lifetime: 86400000
turn_allow_guests: true
이건 사실 matrix 공식 가이드대로 하기만 하면 돼서 쓰기 뭐한데... 그렇습니다.
이거면 설정 끝! 자료도 많고 가이드도 잘 되어있어서 꽤 쉬웠어요. 오히려 자료가 너무 많아서 좀 헤맸습니다. turnserver.conf 설정은 matrix 가이드 따라하세요. 저처럼 coturn 설정 보고 다 챙기려다 실패하지 말고.
원하는 경로에 matrix 폴더를 만들고 그 안에 docker-compose.yml을 만들어 다음 내용을 작성한다. 폴더는 따로 안 만들어도 동작 하지만 나는 matrix용 폴더를 만들고 그 안에 docker 볼륨이 들어갈 폴더를 만들었다.
services:
synapse:
image: matrixdotorg/synapse
restart: always
ports:
- 8008:8008
volumes:
- [볼륨을 물릴 경로]:/data
docker run -it --rm -v [볼륨을 물릴 경로]:/data -e SYNAPSE_SERVER_NAME=[서버를 돌릴 도메인 주소] -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:latest generate
동작시키면 [볼륨을 물릴 경로]에 homeserver.yaml 파일이 생긴다. 이 파일에서 가입을 열고 다른 설정을 할 수 있다.
위 명령어가 잘 동작했다면 서버의 8008 포트에 접속해본다.
위와 같은 화면이 뜨면 성공적으로 올라간 것이다.
nginx는 설치되어 있다는 가정 하에, /etc/nginx/sites-available/
경로에 매트릭스를 위한 config파일을 하나 만든다. 파일명은 알아만 볼 수 있으면 된다.
기본적인 내용은 다음과 같다
server {
server_name [서버를 돌릴 도메인 주소];
location ~ ^(/_matrix|/_synapse/client) {
proxy_pass http://localhost:8008;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
client_max_body_size 50M;
proxy_http_version 1.1;
}
}
위 내용으로 config 파일을 만들었다면
ln -s /etc/nginx/sites-available/[설정파일명] /etc/nginx/sites-enabled/[설정파일명]
을 수행한 후 nginx -t
명령으로 설정에 문제가 없는지 확인한다.
systemctl restart nginx
nginx를 재시작한다.
nginx가 제대로 돌아가려면 방화벽에서 80번 포트와 443 포트가 열려있어야 한다. 그걸 위해 아래 명령을 수행하거나 또는 다른 툴을 이용해 방화벽을 열어준다.
ufw allow 'Nginx Full'
certbot을 이용해 인증서를 발급받는다. 이 과정 설명은 생략한다.
인증서를 발급받으면 방금 설정한 nginx 설정 아래쪽에 listen 443 ssl; # managed by Certbot
로 시작하는 코드가 몇 줄 생겼을 것이다. 그 위에 listen 8448 ssl;
를 추가해준다.
기존의 location
과 listen ...
사이에 다음 코드를 추가해준다.
location /.well-known/matrix/client {
return 200 '{"m.server": {"base_url": "[서비스할 도메인 주소]:443"}}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
location /.well-known/matrix/server {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.server":"[서비스할 도메인 주소]:443"}';
}
바로 위의 /.well-known/...
설정은 메인 도메인 nginx 설정에 넣어준다. 코드 내부에 넣을 주소는 실제 서비스가 돌아가고 있는 서브도메인 주소를 넣으면 된다.
[볼륨을 물릴 경로]
내부의 파일을 다 지운다. 그 후 docker compose down을 이용해 서버를 내리고
docker run -it --rm -v [볼륨을 물릴 경로]:/data -e SYNAPSE_SERVER_NAME=[핸들로 사용할 도메인] -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:latest generate
위 명령어를 실행한다.
[볼륨을 물릴 경로]/homeserver.yaml
을 열어 enable_registration: true
를 추가한다.
이후 docker compose를 올리면 되는데...
내가 해봤을 때 뭔가 설정을 추가해달라는 요구가 뜨며 오류가 났었다. 정확히 무슨 옵션을 추가하라고 했었는지는 기억이 나지 않으니 docker compose up
명령어를 이용해 직접 확인해서 추가하면 된다. 모든 옵션 설정이 끝나면
docker compose up -d
로 서버를 백그라운드에 올려서 완료.
여기서 끝인 줄 알았는데 object storage를 연결해야한다는 걸 알게됐다. 버킷 없이 관리할 수도 있지만 자신이 없어서 물려놓기로 했다. 문제는 직접 설치한 게 아니라 도커로 서버를 올렸다는 것.
직접 설치했을 경우 matrix.org에서 제공하는 synapse-s3-storage-provider를 이용할 수 있으나 도커로 올리면 방법이 없다.
검색을 반복한 끝에 [볼륨을 물릴 경로]/media_store
에 rclone으로 오브젝트 스토리지를 mount 하기로 했다. 각자의 object storage의 특성에 맞춰 mount해서 사용하면 된다. media_store는 기본 설정이므로 homeserver.yaml
파일에서 설정을 바꿀 수 있다.
https://theselfhostingblog.com/posts/self-hosting-your-own-matrix-server-on-a-raspberry-pi/ https://matrix-org.github.io/synapse/latest/