Running a server
Administration and settings
The admin page, delivering sign-up codes (SMS and email), server settings, backups and security โ a reference for operators.
The server includes an admin page that you open in a browser. It shows the server's status, lets you decide how sign-up and sign-in codes are delivered, and manages users and bots. This page is a reference that gathers the admin page and the server's settings in one place. If you still need to install the server, see Server installation first.
The admin page's interface is in Korean. Below, each tab, button and setting is given with an English name, followed by its Korean label as it appears on screen.
Opening the admin page
The admin page is at /admin/ on the management HTTP port (8080 in the production setup), and it's open only on the server itself (127.0.0.1). Operators get in through an SSH tunnel.
# On your computer (leave it running)
ssh -N -L 8080:127.0.0.1:8080 <user>@<server>
# Browser: http://localhost:8080/admin/
# The token (on the server)
sudo cat /srv/pabal/pabal_server/data/admin-token
Enter the token and click Open (์ด๊ธฐ). The browser remembers the token; remove it with Clear token (ํ ํฐ ์ง์ฐ๊ธฐ) at the top right. To choose the token yourself, set TELEGRAM_ADMIN_TOKEN (16 or more characters) โ the file is then not written.
What each tab shows
| Tab | Contents | Refresh |
|---|---|---|
| Dashboard (๋์๋ณด๋) | People, sessions and connections online right now; numbers of people, bots, groups, messages and photos; uptime, ports and DB; JVM; health checks. A warning banner if test numbers are on | 5 seconds |
| Sign-up codes (๊ฐ์ ์ฝ๋) | Pending codes (number, delivery method, delivery status, code, time left, wrong attempts) and recent activity. Copy (๋ณต์ฌ) or cancel (์ทจ์) a code | 3 seconds |
| Users (์ฌ์ฉ์) | Every account โ phone number, sign-in email (editable), whether online, number of signed-in devices, number of messages. Sign out all devices (๋ชจ๋ ๊ธฐ๊ธฐ ๋ก๊ทธ์์), Block number (๋ฒํธ ์ฐจ๋จ) | 10 seconds |
| Bots (๋ด) | Bots created with BotFather โ creator, command menu, how they connect (MTProto ยท HTTP polling ยท webhook address and failure reason), number of waiting updates | 10 seconds |
| Settings (์ค์ ) | Sign-up and sign-in rules, SMS, email (SMTP), blocked phone numbers | Saved manually |
| Storage (์ ์ฅ์) | Data directory and DB address (password hidden), number and total size of photos, number of stored streams by kind | 10 seconds |
Dangerous actions (signing out, blocking, cancelling a code) only run when you click twice.
Sign-up and sign-in codes
When someone enters a phone number in the app, the server creates a code and sends it by the method chosen in the Settings (์ค์ ) tab.
| Delivery method | Where the code goes | App screens |
|---|---|---|
| Admin page (๊ด๋ฆฌ ํ๋ฉด) | The Sign-up codes (๊ฐ์ ์ฝ๋) tab. The operator copies it and passes it on personally | Number โ "code sent" โ code (name, for a new number) |
| SMS | A text message through one of Twilio ยท Solapi ยท webhook | Same as the admin page |
| Email (์ด๋ฉ์ผ) | An email over SMTP | Number โ enter email โ "code sent by email" โ code |
- With the email method, a new sign-up can use any address, and that address becomes the account's sign-in email (๋ก๊ทธ์ธ ์ด๋ฉ์ผ). Existing accounts receive codes only at their registered sign-in email โ this stops people from getting into someone else's number by entering their own address. Existing accounts without a sign-in email get their code by SMS (if configured) or through the admin page instead. You can add a sign-in email in the Users (์ฌ์ฉ์) tab.
- Sending happens in the background, so the app goes straight to the code screen. The result of sending (success or failure, with the reason) appears in the Sign-up codes tab.
- Signing up (entering a name) is possible only after entering the right code. Wrong codes are accepted only up to the allowed number of tries; after that, even the right code is refused.
Settings โ sign-up and sign-in
| Setting | Meaning | Default |
|---|---|---|
| Allow new sign-ups (์ ๊ฐ์ ํ์ฉ) | When off, only existing accounts can sign in. New numbers are rejected as an "invalid number" | On |
| Code delivery method (์ฝ๋ ์ ๋ฌ ๋ฐฉ์) | Admin page / SMS / Email | Admin page |
| Show codes on the admin page (๊ด๋ฆฌ ํ๋ฉด์ ์ฝ๋ ํ์) | Shows codes in the Sign-up codes tab even with the SMS and email methods (in case sending fails) | On |
| Test numbers (+99966โฆ) (ํ ์คํธ ๋ฒํธ) | As in server config (์๋ฒ ์ค์ ๋๋ก) / On (์ผ๊ธฐ) / Off (๋๊ธฐ). Off in production | As in server config |
| Code length (์ฝ๋ ์๋ฆฟ์) ยท validity (์ฝ๋ ์ ํจ ์๊ฐ (๋ถ)) | 5โ6 digits ยท 1โ60 minutes | 5 digits ยท 5 minutes |
| Resend interval (์ฌ์์ฒญ ๊ฐ๊ฒฉ (์ด)) ยท daily maximum (๋ฒํธ๋น ํ๋ฃจ ์ต๋ ์์ฒญ) | Seconds before the same number can get another code (0โ3600) ยท maximum number of times within 24 hours (1โ1000) | 60 seconds ยท 10 times |
| Allowed wrong attempts (ํ๋ฆฐ ์ ๋ ฅ ํ์ฉ ํ์) | Beyond this, the code is locked (1โ20) | 5 times |
Settings โ SMS
| Provider (์ ๊ณต์) | Values to enter | Notes |
|---|---|---|
| Webhook (์นํ ) | The receiving address (https://โฆ) (์นํ ์ฃผ์), an Authorization header (optional) | The server sends POST {"phone":"+8210โฆ","code":"12345","text":"โฆ"}. A 2xx means success. For connecting your own SMS server or another service |
| Twilio | Account SID, Auth Token, a sender number (๋ฐ์ ๋ฒํธ) or a Messaging Service SID | Worldwide, including numbers outside Korea |
| Solapi (formerly CoolSMS) | API Key, API Secret, sender number | Domestic Korean text messages. The sender number must be registered in advance with Solapi. +82 numbers are sent in the 010โฆ format |
The message text (๋ฌธ๊ตฌ) can include {code} (the code) and {minutes} (how long it's valid). Default: [ํ๋ฐ] ์ธ์ฆ ์ฝ๋: {code} ("[Pabal] Verification code: {code}"). After saving (์ ์ฅ), check it with Send test (ํ
์คํธ ๋ฐ์ก).
Settings โ email (SMTP)
| Service | Server (SMTP ์๋ฒ) ยท port (ํฌํธ) ยท security (๋ณด์) | Username (์ฌ์ฉ์๋ช ) ยท password (๋น๋ฐ๋ฒํธ) |
|---|---|---|
| Gmail | smtp.gmail.com ยท 587 ยท STARTTLS | Your Gmail address ยท an app password (Google Account โ Security โ 2-Step Verification โ App passwords) |
| Naver | smtp.naver.com ยท 587 ยท STARTTLS | Naver ID ยท password (turn on POP3/SMTP in the mail settings) |
| In-house mail relay | Relay address ยท 25 ยท none (์์) | Leave empty |
The sender address (๋ณด๋ด๋ ์ฃผ์) must be one the SMTP account is allowed to send from. You can use {code} and {minutes} in the subject (์ ๋ชฉ) and body (๋ณธ๋ฌธ) as well.
Managing users
- Sign out all devices (๋ชจ๋ ๊ธฐ๊ธฐ ๋ก๊ทธ์์): cuts off every sign-in (auth key) of that account. Use it for users who have lost a device.
- Block number (๋ฒํธ ์ฐจ๋จ): that number can no longer receive codes, and its account is immediately signed out on every device. It's the same as the Block phone numbers (์ ํ๋ฒํธ ์ฐจ๋จ) list in the Settings (์ค์ ) tab.
- Sign-in email (๋ก๊ทธ์ธ ์ด๋ฉ์ผ): needed for an existing account to sign in by email when the email method is used.
- @BotFather is a bot inside the server, so it can't be signed out.
Managing bots
The Bots (๋ด) tab shows how each bot connects โ whether it's connected over MTProto, whether it called getUpdates over HTTP within the last minute, and what its webhook address is and whether it's currently failing (with the reason). If the number of waiting updates keeps growing, the bot program has stopped or its webhook is failing. Deleting a bot or issuing a new token is done by the bot's creator at @BotFather.
Environment variables
The server reads its settings file (server-config.json) and then overrides it with environment variables. The production compose file sets the values below, so usually you only need to edit .env.
| Variable | Meaning | Production compose value |
|---|---|---|
TELEGRAM_PORT | MTProto port | MTPROTO_PORT (8443) |
TELEGRAM_HOST | Address MTProto listens on | 0.0.0.0 |
TELEGRAM_PUBLIC_HOST | Server address announced to the app (help.getConfig) | PUBLIC_IP |
TELEGRAM_WEB_PORT | Port for the website, docs, Bot API and admin page | 8080 |
TELEGRAM_WEB_HOST | Address that port listens on. Default 127.0.0.1 | 0.0.0.0 (inside the container; exposed on the host only as 127.0.0.1) |
TELEGRAM_PUBLIC_URL | Website address. Used for links (me_url_prefix), invite links, examples in the docs and preview images | https://DOMAIN/ |
TELEGRAM_DATA_DIR | Location of photos, admin-token and operations.json | /app/data |
TELEGRAM_RSA_KEY | Path of the server's RSA private key (created on first start if missing; the public key is .pub) | /app/keys/private.pem |
TELEGRAM_DC_ID | This server's DC number | (image default 1) |
TELEGRAM_DB_TYPE | memory ยท h2 ยท postgresql | postgresql |
TELEGRAM_DB_URL, TELEGRAM_DB_USERNAME, TELEGRAM_DB_PASSWORD | JDBC connection | jdbc:postgresql://pabal-postgres:5432/pabal, pabal, POSTGRES_PASSWORD |
TELEGRAM_DB_MAX_POOL_SIZE | Number of DB connections | 20 |
TELEGRAM_ADMIN_TOKEN | Admin page token (if empty, created in data/admin-token) | ADMIN_TOKEN |
TELEGRAM_TEST_NUMBERS | +99966โฆ test numbers. Development only | false |
TELEGRAM_WEBHOOK_ALLOW_LOCAL | Lets bot webhooks use http:// and internal addresses. Development only | (not set = false) |
JAVA_OPTS | JVM options (memory) | The value from .env |
Data files
| File | Contents | Permissions |
|---|---|---|
keys/private.pem | The server's RSA private key. Never let it leave the server | 600 |
keys/private.pem.pub | The public key. Used for building the app and for /docs/server-key.pem | โ |
data/admin-token | The admin page token | 600 |
data/operations.json | The values from the Settings (์ค์ ) tab โ sign-up rules, SMS and SMTP secrets, blocked numbers | 600 |
data/media/ | Original photos | โ |
PostgreSQL events table | Accounts, conversations, messages, sign-ins, bots, webhook settings โ the record of every change | โ |
Security notes
- Don't expose the management port directly to the internet. In the production setup, Caddy blocks management paths such as
/admin,/healthand/metricswith a 404. - Every admin data request needs
Authorization: Bearer <token>, and pages on other sites can't read it. - SMS and SMTP secrets exist only in
operations.json; the screen and the API only tell you that a value is "saved" (์ ์ฅ๋จ). If you save with a secret field left empty, the existing value is kept. - Tokens and secrets are never written to the logs, and phone numbers in the logs are masked. Bot API addresses (which include the token) aren't logged either.
- The auth keys are in the DB, so anyone who can access the DB can decrypt users' traffic. Guard the DB and backups as carefully as the RSA key.
Limitations
- Pending codes and recent activity are held in memory, so they're lost when the server restarts (people just request a code again in the app).
- Actual delivery through an SMS provider has to be verified with each provider's account. The server builds its requests as described in each provider's documentation.
- Not available yet: deleting accounts, force-deleting bots, reading messages, viewing logs, graphs.