================================================================ УСТАНОВКА СЕРВЕРА ICQ (Open OSCAR Server) Полный технический отчёт Сервер: 192.168.50.115 / публичный 109.194.162.9 ОС: Ubuntu 24.04.5 LTS (noble), x86_64 Дата: 25.10.2026 ================================================================ Скачать этот файл: https://chat.nexcloud72.duckdns.org/ICQ-INSTALL.txt Инструкция для пользователей: https://chat.nexcloud72.duckdns.org/ICQ-README.txt ВНИМАНИЕ: этот файл публичный. Паролей и ключей в нём нет. ---------------------------------------------------------------- 1. ЧТО УСТАНОВЛЕНО ---------------------------------------------------------------- Сервер: Open OSCAR Server v0.25.0 (open-source, MIT) Репозиторий: https://github.com/mk6i/open-oscar-server Релиз: https://github.com/mk6i/open-oscar-server/releases/tag/v0.25.0 Компоненты: /opt/open-oscar-server/open_oscar_server сам ICQ/AIM-сервер (Go) /etc/open-oscar/settings.env конфигурация /var/lib/open-oscar/oscar.sqlite база пользователей (SQLite) open-oscar.service systemd-служба ICQ-сервера /opt/icq-register/regserver.py публичная регистрация UIN icq-register.service systemd-служба регистрации /var/www/icq-site/ сайт chat.nexcloud72.duckdns.org /var/www/icq-acme/ ACME-каталог Let's Encrypt Apache vhosts zz-icq*.conf, zz-chat*.conf HTTPS и прокси Пользователи системы: oscar — системный пользователь для ICQ-сервера www-data — для сайта и сервиса регистрации Публичные адреса: https://chat.nexcloud72.duckdns.org/ сайт + регистрация https://icq.nexcloud72.duckdns.org/ WebAPI для мобильных клиентов 109.194.162.9:5190 TCP ICQ/OSCAR из интернета 109.194.162.9:4000 UDP старый ICQ (98-2003) 109.194.162.9:9898 TCP TOC 192.168.50.115:5191 TCP ICQ/OSCAR в локальной сети ---------------------------------------------------------------- 2. ИСХОДНОЕ СОСТОЯНИЕ СЕРВЕРА ---------------------------------------------------------------- Проверка перед установкой: uname -a Linux ... 6.8.0-147-generic x86_64 /etc/os-release Ubuntu 24.04.5 LTS nproc 4 free -h 15 GiB RAM df -h / 39 GB свободно ss -tlnp порт 5190 свободен На сервере уже работали: apache2 (Virtualmin: music.lan, nexcloud72.duckdns.org), mariadb, dovecot, postfix, named (BIND), redis, memcached, webmin (порты 10000/20000). Их конфигурацию не меняли. Firewall: firewalld активен, ufw неактивен. NAT/роутер уже пробрасывал 80/443 и 5190 на 192.168.50.115. ---------------------------------------------------------------- 3. СКАЧИВАНИЕ И ПРОВЕРКА ---------------------------------------------------------------- Команды (на сервере): cd /tmp mkdir oos_pkg && cd oos_pkg curl -sSLO https://github.com/mk6i/open-oscar-server/releases/download/v0.25.0/open_oscar_server.0.25.0.linux.x86_64.tar.gz curl -sSLO https://github.com/mk6i/open-oscar-server/releases/download/v0.25.0/open-oscar-server_0.25.0_checksums.txt sha256sum open_oscar_server.0.25.0.linux.x86_64.tar.gz # 35d0f9bbab43761769b2d789485bdae25892acc0d1f2c8f3cf6361f28d0081ea Сверка с официальным checksums.txt: совпало. Содержимое архива: LICENSE ras.service settings.env open_oscar_server Бинарник статический (Go), внешние библиотеки не нужны: file open_oscar_server # ELF 64-bit LSB executable, x86-64, statically linked, stripped ./open_oscar_server -version # version: 0.25.0 # commit: 1ab851e83e58c7c0f8a68c670676b95fa43451c9 ---------------------------------------------------------------- 4. ПОЛЬЗОВАТЕЛЬ И КАТАЛОГИ ---------------------------------------------------------------- useradd --system --home-dir /var/lib/open-oscar \ --create-home --shell /usr/sbin/nologin oscar install -d -o oscar -g oscar -m 0750 /var/lib/open-oscar install -d -o root -g root -m 0755 /opt/open-oscar-server install -d -o root -g oscar -m 0750 /etc/open-oscar install -o root -g root -m 0755 open_oscar_server \ /opt/open-oscar-server/open_oscar_server install -o root -g root -m 0644 LICENSE \ /opt/open-oscar-server/LICENSE Права на конфиг: chown root:oscar /etc/open-oscar/settings.env chmod 0640 /etc/open-oscar/settings.env ---------------------------------------------------------------- 5. КОНФИГУРАЦИЯ: /etc/open-oscar/settings.env ---------------------------------------------------------------- Файл создан вручную. Полное содержимое: ---------------------------------------------------------------- # Open OSCAR Server configuration (ICQ/AIM) # Core OSCAR listeners: WAN (internet) + LAN on a separate port export OSCAR_LISTENERS=WAN://0.0.0.0:5190,LAN://192.168.50.115:5191 # Addresses advertised to clients export OSCAR_ADVERTISED_LISTENERS_PLAIN=WAN://109.194.162.9:5190,LAN://192.168.50.115:5191 # TOC protocol (older third-party clients) export TOC_LISTENERS=0.0.0.0:9898 # Management API stays local only export API_LISTENER=127.0.0.1:8080 # WebAPI (mobile/web clients) - exposed via Apache reverse proxy at # https://icq.nexcloud72.duckdns.org/ export WEBAPI_ENABLED=true export WEBAPI_LISTENERS=127.0.0.1:8081 export WEBAPI_ALLOWED_ORIGINS=https://icq.nexcloud72.duckdns.org,https://chat.nexcloud72.duckdns.org,http://109.194.162.9,https://109.194.162.9,http://localhost:* # Database export DB_PATH=/var/lib/open-oscar/oscar.sqlite # Authentication: accounts are created via the Management API export DISABLE_AUTH=false export DISABLE_MULTI_LOGIN_NOTIF=false export LOG_LEVEL=info # Russian-language fallback for legacy clients export ICBM_LEGACY_CHARSET=Windows1251 # Legacy ICQ protocol (ICQ 98 - 2003, QIP, Jimm and other old clients) export ICQ_LEGACY_ENABLED=true export ICQ_LEGACY_UDP_LISTENER=0.0.0.0:4000 export ICQ_LEGACY_VERSIONS=2,3,4,5 export ICQ_LEGACY_SESSION_TIMEOUT=120s export ICQ_LEGACY_KEEPALIVE_INTERVAL=120s export ICQ_LEGACY_AUTO_REGISTRATION=false export ICQ_LEGACY_DEPARTMENTS_ENABLED=false export ICQ_LEGACY_BROADCAST_ENABLED=true export ICQ_LEGACY_WWP_ENABLED=true export ICQ_LEGACY_DIRECT_CONNECTIONS=5 ---------------------------------------------------------------- Пояснения: DISABLE_AUTH=false — свободной авторегистрации при входе нет; аккаунты создаются только через Management API или сайт. API_LISTENER=127.0.0.1 — управление доступно только с сервера. WAN/LAN — два слушателя: интернет на 5190, локальная сеть на 5191. ICQ_LEGACY_* — поддержка старых ICQ-клиентов и UDP 4000. ---------------------------------------------------------------- 6. SYSTEMD: /etc/systemd/system/open-oscar.service ---------------------------------------------------------------- Полное содержимое: ---------------------------------------------------------------- [Unit] Description=Open OSCAR Server (ICQ/AIM) Documentation=https://github.com/mk6i/open-oscar-server After=network-online.target Wants=network-online.target [Service] Type=simple User=oscar Group=oscar WorkingDirectory=/var/lib/open-oscar ExecStart=/opt/open-oscar-server/open_oscar_server -config /etc/open-oscar/settings.env Restart=on-failure RestartSec=3 TimeoutStopSec=20 LimitNOFILE=65536 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/lib/open-oscar [Install] WantedBy=multi-user.target ---------------------------------------------------------------- Применение: systemctl daemon-reload systemctl enable --now open-oscar systemctl status open-oscar Проверка конфигурации сервером (в логах): Successfully loaded config file (/etc/open-oscar/settings.env) starting server svc=OSCAR listener=wan listen_address=0.0.0.0:5190 starting server svc=OSCAR listener=lan listen_address=192.168.50.115:5191 legacy ICQ server started address=0.0.0.0:4000 versions="[2 3 4 5]" ---------------------------------------------------------------- 7. ПУБЛИЧНАЯ РЕГИСТРАЦИЯ UIN ---------------------------------------------------------------- 7.1. /opt/icq-register/regserver.py Небольшой сервис на Python 3 (только стандартная библиотека). Слушает 127.0.0.1:8090, наружу опубликован через Apache. Что делает: - принимает POST /api/register с JSON {"uin":"...","password":"..."}; - проверяет UIN: 5-10 цифр, диапазон 10000..2147483646, без ведущего нуля; - проверяет пароль: 6-8 символов [A-Za-z0-9!@#$%^&*()._+-]; - если UIN пустой — генерирует свободный 9-значный; - проверяет занятость UIN через GET http://127.0.0.1:8080/user; - создаёт аккаунт через POST http://127.0.0.1:8080/user; - ограничение: 5 регистраций в час на IP (X-Forwarded-For); - honeypot-поле "website" для отсечения ботов; - CORS только для https://chat.nexcloud72.duckdns.org; - GET /api/health — проверка живости. Ключевые константы: MGMT_API = "http://127.0.0.1:8080" HOST, PORT = "127.0.0.1", 8090 UIN_MIN = 10000 UIN_MAX = 2147483646 RATE_LIMIT = 5 за 3600 секунд ALLOW_ORIGIN = "https://chat.nexcloud72.duckdns.org" Полный исходник остаётся на сервере: /opt/icq-register/regserver.py Права: chmod 0755 /opt/icq-register/regserver.py 7.2. /etc/systemd/system/icq-register.service Полное содержимое: ---------------------------------------------------------------- [Unit] Description=ICQ public registration API After=network-online.target open-oscar.service Wants=network-online.target [Service] Type=simple User=www-data Group=www-data WorkingDirectory=/opt/icq-register ExecStart=/usr/bin/python3 /opt/icq-register/regserver.py Restart=on-failure RestartSec=3 NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ProtectKernelTunables=true ProtectControlGroups=true RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX MemoryMax=128M [Install] WantedBy=multi-user.target ---------------------------------------------------------------- Применение: systemctl daemon-reload systemctl enable --now icq-register curl http://127.0.0.1:8090/api/health ---------------------------------------------------------------- 8. САЙТ: /var/www/icq-site ---------------------------------------------------------------- install -d -o root -g root -m 0755 /var/www/icq-site Файлы: index.html лендинг: форма регистрации, инструкции, ссылки ICQ-README.txt инструкция для пользователей (скачивание) ICQ-INSTALL.txt этот технический отчёт Права: chmod 0644 /var/www/icq-site/index.html \ /var/www/icq-site/ICQ-README.txt \ /var/www/icq-site/ICQ-INSTALL.txt index.html — один самодостаточный файл: CSS и JS встроены, внешних библиотек нет. Форма отправляет POST /api/register, после успеха показывает UIN. Есть кнопки скачивания инструкций. Сайт статический, PHP/БД не использует. ---------------------------------------------------------------- 9. APACHE: ВИРТУАЛЬНЫЕ ХОСТЫ ---------------------------------------------------------------- Модули: a2enmod headers (proxy, proxy_http, ssl, rewrite уже были включены) ВАЖНО: файлы названы с префиксом zz-, чтобы vhost music.lan остался сервером по умолчанию для 80/443 (Apache берёт первый по алфавиту). Иначе запросы по IP/неизвестному Host попадали бы в ICQ-прокси. 9.1. /etc/apache2/sites-available/zz-icq.conf (порт 80, ACME) ---------------------------------------------------------------- ServerName icq.nexcloud72.duckdns.org DocumentRoot /var/www/icq-acme ErrorLog /var/log/apache2/icq_error.log CustomLog /var/log/apache2/icq_access.log combined Require all granted RewriteEngine On RewriteCond %{REQUEST_URI} !^/\.well-known/ RewriteRule ^/(.*)$ https://icq.nexcloud72.duckdns.org/$1 [R=301,L] ---------------------------------------------------------------- 9.2. /etc/apache2/sites-available/zz-icq-le-ssl.conf (443 -> WebAPI) ---------------------------------------------------------------- ServerName icq.nexcloud72.duckdns.org DocumentRoot /var/www/icq-acme ErrorLog /var/log/apache2/icq_error.log CustomLog /var/log/apache2/icq_access.log combined SSLEngine on SSLCertificateFile /etc/letsencrypt/live/icq.nexcloud72.duckdns.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/icq.nexcloud72.duckdns.org/privkey.pem SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 ProxyRequests Off ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" ProxyPass / http://127.0.0.1:8081/ retry=0 timeout=60 ProxyPassReverse / http://127.0.0.1:8081/ Require all granted ---------------------------------------------------------------- Почему весь путь /, а не /oscar/: WebAPI строит абсолютные ссылки из заголовка Host (scheme://host/), префикс пути он не учитывает. Поэтому API публикуется в корне отдельного имени icq.*. 9.3. /etc/apache2/sites-available/zz-chat.conf (порт 80) ---------------------------------------------------------------- ServerName chat.nexcloud72.duckdns.org DocumentRoot /var/www/icq-site ErrorLog /var/log/apache2/chat_error.log CustomLog /var/log/apache2/chat_access.log combined Require all granted RewriteEngine On RewriteCond %{REQUEST_URI} !^/\.well-known/ RewriteRule ^/(.*)$ https://chat.nexcloud72.duckdns.org/$1 [R=301,L] ---------------------------------------------------------------- 9.4. /etc/apache2/sites-available/zz-chat-le-ssl.conf (443, сайт) ---------------------------------------------------------------- ServerName chat.nexcloud72.duckdns.org DocumentRoot /var/www/icq-site ErrorLog /var/log/apache2/chat_error.log CustomLog /var/log/apache2/chat_access.log combined SSLEngine on SSLCertificateFile /etc/letsencrypt/live/chat.nexcloud72.duckdns.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/chat.nexcloud72.duckdns.org/privkey.pem SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 Require all granted AddCharset UTF-8 .txt ProxyRequests Off ProxyPreserveHost On RequestHeader set X-Forwarded-Proto "https" RequestHeader unset Expect early ProxyPass /api/ http://127.0.0.1:8090/api/ retry=0 timeout=30 ProxyPassReverse /api/ http://127.0.0.1:8090/api/ Header always set X-Content-Type-Options "nosniff" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set X-Frame-Options "SAMEORIGIN" ---------------------------------------------------------------- RequestHeader unset Expect early нужен, чтобы Apache не передавал POST с "Expect: 100-continue" в Python-сервис (иначе таймаут). Сам Python-сервис тоже умеет отвечать 100 Continue. Применение: a2ensite zz-icq zz-icq-le-ssl zz-chat zz-chat-le-ssl apache2ctl configtest systemctl reload apache2 Проверка default-сервера: apache2ctl -S | grep 'default server' # default server music.lan ... ---------------------------------------------------------------- 10. LET'S ENCRYPT ---------------------------------------------------------------- DNS: DuckDNS поддерживает wildcard для nexcloud72.duckdns.org, поэтому icq.* и chat.* резолвятся на 109.194.162.9 без дополнительных записей. Каталоги ACME: install -d -o www-data -g www-data -m 0755 \ /var/www/icq-acme/.well-known/acme-challenge install -d -o root -g root -m 0755 /var/www/icq-site Выпуск сертификатов: certbot certonly --webroot -w /var/www/icq-acme \ -d icq.nexcloud72.duckdns.org \ --non-interactive --agree-tos \ --register-unsafely-without-email --keep-until-expiring certbot certonly --webroot -w /var/www/icq-site \ -d chat.nexcloud72.duckdns.org \ --non-interactive --agree-tos \ --register-unsafely-without-email --keep-until-expiring Сертификаты: /etc/letsencrypt/live/icq.nexcloud72.duckdns.org/ /etc/letsencrypt/live/chat.nexcloud72.duckdns.org/ Автопродление: systemctl enable --now certbot.timer systemctl list-timers certbot.timer Hook для перезагрузки Apache после продления: /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh ---------------------------------------------------------------- #!/bin/sh systemctl reload apache2 ---------------------------------------------------------------- chmod 0755 /etc/letsencrypt/renewal-hooks/deploy/reload-apache.sh ---------------------------------------------------------------- 11. FIREWALL И NAT ---------------------------------------------------------------- Firewalld (постоянные правила): firewall-cmd --permanent \ --add-port=5190/tcp --add-port=5191/tcp \ --add-port=4000/udp --add-port=9898/tcp firewall-cmd --reload firewall-cmd --permanent --list-ports Открыто: 5190/tcp ICQ/OSCAR (интернет) 5191/tcp ICQ/OSCAR (LAN) 4000/udp старый ICQ 9898/tcp TOC 80/tcp HTTP -> HTTPS 443/tcp HTTPS Не открыты наружу (только 127.0.0.1): 8080/tcp Management API 8081/tcp WebAPI 8090/tcp регистрация На роутере проброшены на 192.168.50.115: 80/tcp, 443/tcp, 5190/tcp, 4000/udp (это уже было настроено; 5190/4000 проверены снаружи). ---------------------------------------------------------------- 12. ЗАПУСК И АВТОЗАПУСК ---------------------------------------------------------------- systemctl daemon-reload systemctl enable --now open-oscar systemctl enable --now icq-register systemctl enable apache2 firewalld certbot.timer Проверка: systemctl is-enabled open-oscar icq-register apache2 systemctl is-enabled firewalld certbot.timer systemctl is-active open-oscar icq-register apache2 Все службы: enabled + active. Перезагрузка сервера проверена дважды: - boot_id менялся, uptime сбрасывался; - systemd: running, failed units: нет; - все службы поднимались автоматически; - база пользователей сохранялась; - внешний TCP 5190 был доступен сразу после загрузки; - реальный вход клиента (user signed on) подтверждён. ---------------------------------------------------------------- 13. КАК ПРОВЕРЯЛОСЬ СНАРУЖИ ---------------------------------------------------------------- TCP 5190: https://check-host.net/check-tcp?host=109.194.162.9:5190 Успешно из Германии, Венгрии, Ирана, Японии, Израиля и др. UDP 4000: https://check-host.net/check-udp?host=109.194.162.9:4000 "timeout" — нормально: OSCAR не отвечает на пустые пакеты. Факт прихода пакетов подтверждён tcpdump на сервере (источники: 195.154.114.92, 107.149.201.15 и др.). HTTPS: check-host HTTP: 200 из Германии, Молдовы, Словении. tcpdump: timeout 60 tcpdump -ni any 'tcp port 5190 or udp port 4000' \ -w /tmp/probe.pcap tcpdump -nr /tmp/probe.pcap В логах Apache был внешний клиент, в логах open-oscar: user signed on svc=OSCAR screenName=... ip=... Строки "user session failed ... EOF" — это сканеры портов, которые подключаются и сразу отключаются. Не ошибка сервера. ---------------------------------------------------------------- 14. УДАЛЁННЫЙ СТАРЫЙ ЮНИТ ---------------------------------------------------------------- После перезагрузки systemd был в состоянии degraded из-за файла /etc/systemd/system/icq-legacy.service (остаток прежней попытки установки). Он ссылался на несуществующих пользователя ras и каталоги /opt/ras, /var/lib/ras, падал с 217/USER. Проверено: пользователя и каталогов нет, данных нет. Юнит отключён и удалён: systemctl disable icq-legacy rm -f /etc/systemd/system/icq-legacy.service systemctl daemon-reload systemctl reset-failed После этого: systemctl is-system-running -> running. ---------------------------------------------------------------- 15. ОБСЛУЖИВАНИЕ ---------------------------------------------------------------- Состояние: systemctl status open-oscar icq-register apache2 Логи: journalctl -u open-oscar -f journalctl -u icq-register -f tail -f /var/log/apache2/chat_access.log tail -f /var/log/apache2/chat_error.log tail -f /var/log/apache2/icq_access.log Пользователи (только с сервера): curl http://127.0.0.1:8080/user curl -d '{"screen_name":"100004","password":"pass1234"}' \ http://127.0.0.1:8080/user curl -X DELETE -d '{"screen_name":"100004"}' \ http://127.0.0.1:8080/user curl -X PUT \ -d '{"screen_name":"100004","password":"new12345"}' \ http://127.0.0.1:8080/user/password Сессии: curl http://127.0.0.1:8080/session Перезапуск: systemctl restart open-oscar systemctl restart icq-register systemctl reload apache2 Проверка конфигов Apache: apache2ctl configtest Проверка сайта/API: curl -I https://chat.nexcloud72.duckdns.org/ curl -I https://chat.nexcloud72.duckdns.org/ICQ-README.txt curl -I https://icq.nexcloud72.duckdns.org/ curl https://chat.nexcloud72.duckdns.org/api/health ---------------------------------------------------------------- 16. РЕЗЕРВНОЕ КОПИРОВАНИЕ ---------------------------------------------------------------- База пользователей: cp /var/lib/open-oscar/oscar.sqlite \ /root/oscar-$(date +%F).sqlite Восстановление: systemctl stop open-oscar cp /root/oscar-2026-10-25.sqlite \ /var/lib/open-oscar/oscar.sqlite chown oscar:oscar /var/lib/open-oscar/oscar.sqlite systemctl start open-oscar Конфиги и сайт: tar czf /root/icq-config-$(date +%F).tgz \ /etc/open-oscar /etc/systemd/system/open-oscar.service \ /etc/systemd/system/icq-register.service \ /etc/apache2/sites-available/zz-icq*.conf \ /etc/apache2/sites-available/zz-chat*.conf \ /opt/icq-register /var/www/icq-site ---------------------------------------------------------------- 17. ЕСЛИ МЕНЯЕТСЯ IP ИЛИ ДОМЕН ---------------------------------------------------------------- При смене публичного IP: - в /etc/open-oscar/settings.env поправить OSCAR_ADVERTISED_LISTENERS_PLAIN=WAN://НОВЫЙ_IP:5190; - на роутере проверить проброс 5190/tcp, 4000/udp, 80/443; - systemctl restart open-oscar. При смене домена: - заменить icq.nexcloud72.duckdns.org и chat.nexcloud72.duckdns.org в vhost-файлах; - обновить WEBAPI_ALLOWED_ORIGINS в settings.env; - обновить ALLOW_ORIGIN в regserver.py; - выпустить новые сертификаты certbot; - перезапустить open-oscar, icq-register, reload apache2. Внимание: DuckDNS-адрес должен резолвиться на публичный IP. Проверка: getent hosts icq.nexcloud72.duckdns.org ---------------------------------------------------------------- 18. БЕЗОПАСНОСТЬ ---------------------------------------------------------------- - Management API (8080) доступен только с localhost. - Наружу опубликована только операция создания аккаунта через regserver.py; удаление/смена пароля недоступны. - Регистрация: лимит 5/час на IP, honeypot, длина тела <= 4 КБ. - Пароли ICQ ограничены 6-8 символами требованиями протокола. - WebAPI и регистрация работают за Apache по HTTPS. - Сертификаты Let's Encrypt продлеваются автоматически. - В этом файле нет паролей и приватных ключей. - Не публикуйте /etc/open-oscar/settings.env и базу SQLite: в них нет паролей в открытом виде (хеши), но это внутренние данные. Проверка, что наружу не торчат служебные порты: ss -tlnp | grep -E ':(8080|8081|8090) ' # все три должны быть 127.0.0.1 ================================================================ КОНЕЦ ================================================================