ডোমেইন, HTTPS এবং রিভার্স প্রক্সি

Antimatter-কে HTTPS-সহ একটি ডোমেইন নামে স্থাপন করুন, কম্পোজ ফাইলের Caddy প্রোফাইল বা আপনার নিজের একটি রিভার্স প্রক্সি ব্যবহার করে, এবং সাইট URL ও ক্লায়েন্ট ঠিকানা সঠিকভাবে সেট করুন।

সাইট URL

সাইট URL (ServiceSettings.SiteURL) হলো সেই ঠিকানা যেটি ব্যবহারকারীরা Antimatter-এ পৌঁছাতে ব্যবহার করেন, যেমন https://chat.example.com। সার্ভার এটি ইমেইল ও নোটিফিকেশনসমূহের লিঙ্কে, সাইন-ইন রিডাইরেক্টে (OAuth, OpenID Connect, SAML), মোবাইল ও ডেস্কটপ অ্যাপসের জন্য, এবং রিকোয়েস্ট কোথা থেকে আসছে তা যাচাই করতে ব্যবহার করে। এটি ব্রাউজারের ঠিকানা বারে থাকা ঠিকানাটির সাথে সম্পূর্ণ মিল রেখে সেট করুন: স্কিম, ডোমেইন এবং ডিফল্ট নয় হলে পোর্ট, শেষে স্ল্যাশ ছাড়া।

  • সাইটের কম্পোজ ফাইলের মাধ্যমে: .env-এ SITE_URL।
  • অন্যত্র: AM_SERVICESETTINGS_SITEURL, অথবা সিস্টেম কনসোল › এনভাইরনমেন্ট › ওয়েব সার্ভার › সাইট URL।

যদি সাইট URL ভুল হয়, তাহলে আইডেন্টিটি প্রোভাইডারের মাধ্যমে সাইন-ইন ব্যর্থ হবে, ইমেইলের লিঙ্ক ভুল জায়গায় নির্দেশ করবে, এবং অ্যাপস সংযোগ স্থাপন করতে নাও পারে। ডোমেইন পরিবর্তনের পর এখানে এবং প্রতিটি আইডেন্টিটি প্রোভাইডারের রিডাইরেক্ট URL-এ এটি আপডেট করুন।

বান্ডল Caddy প্রোফাইলের মাধ্যমে HTTPS

সাইটের compose.yaml-এ https প্রোফাইলে একটি Caddy সার্ভিস রয়েছে। এটি Let's Encrypt-এর থেকে সার্টিফিকেট পায়, নিজে নিজেই তা নবায়ন করে, HTTP-কে HTTPS-এ রিডাইরেক্ট করে এবং সবকিছু, ওয়েবসকিটসহ, Antimatter-এ ফরোয়ার্ড করে।

  1. আপনার ডোমেইনের একটি DNS রেকর্ড (A, এবং IPv6-এর জন্য AAAA) সার্ভারের দিকে নির্দেশ করুন।
  2. ফায়ারওয়ালে পোর্ট 80/tcp, 443/tcp এবং 443/udp (HTTP/3) খুলে দিন। Let's Encrypt-এর ইন্টারনেট থেকে পোর্ট 80 বা 443-এ পৌঁছাতে হবে।
  3. ডোমেইনটি .env-এ যোগ করুন এবং সাইট URL সেট করুন:
    echo "DOMAIN=chat.example.com" >> .env
    sed -i 's|^SITE_URL=.*|SITE_URL=https://chat.example.com|' .env
  4. প্রোফাইলের সাথে শুরু করুন:
    docker compose --profile https up -d

পরে প্রতিটি docker compose up-এ --profile https যোগ করুন, অথবা .env-এ COMPOSE_PROFILES=https রাখুন যাতে সাধারণ docker compose up -d এটি অন্তর্ভুক্ত করে। Caddy তার সার্টিফিকেট https ভলিউমে সংরক্ষণ করে।

Antimatter-এর নিজস্ব পোর্ট হোস্টে প্রকাশিত থাকে (HTTP_PORT, ডিফল্ট 8065)। Caddy সামনে থাকলে এটি শুধুমাত্র সার্ভারের নিজের জন্য রাখুন:

echo "HTTP_PORT=127.0.0.1:8065" >> .env
docker compose --profile https up -d

Caddy Antimatter-এর সাথে অভ্যন্তরীণ edge নেটওয়ার্কের মাধ্যমে যোগাযোগ করে, সেই পোর্টের মাধ্যমে নয়, তাই এটি আপনার ব্যবহারকারীদের জন্য কিছুই পরিবর্তন করে না।

আপনার নিজের রিভার্স প্রক্সি (nginx) ব্যবহার করে

যদি সার্ভারে ইতিমধ্যে nginx বা অন্য কোনো প্রক্সি চালু থাকে, তবে https প্রোফাইলটি বন্ধ রাখুন এবং প্রক্সিটিকে Antimatter-এর পোর্ট 8065-এ পয়েন্ট করুন। প্রক্সিটিকে নিম্নলিখিত কাজগুলো করতে হবে:

  • websocket আপগ্রেড পাস করা (ওয়েব অ্যাপ এবং মোবাইল অ্যাপগুলো /api/v4/websocket-এ একটি websocket খোলা রাখতে থাকে, এবং কিছু অ্যাপ নিজস্ব websocket খোলে);
  • সর্বোচ্চ আপলোডের (সর্বোচ্চ ফাইল সাইজ, ডিফল্ট 100 MB) কমপক্ষে সমান আকারের রিকোয়েস্ট বডি গ্রহণ করুন;
  • দীর্ঘমেয়াদী সংযোগ খোলা রাখা (websocket, বড় আপলোড এবং ডাউনলোডের জন্য);
  • Host হেডার এবং ক্লায়েন্টের ঠিকানা পাস করা।

antimatter-docker-এর প্রোডাকশন টেমপ্লেট থেকে উপযোগী করা একটি সম্পূর্ণ সার্ভার ব্লক। ডোমেইন এবং সার্টিফিকেটের পথগুলো প্রতিস্থাপন করুন:

upstream antimatter {
    server 127.0.0.1:8065;
    keepalive 64;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      '';
}

proxy_cache_path /var/cache/nginx/antimatter levels=1:2 keys_zone=antimatter_cache:10m
                 max_size=3g inactive=120m use_temp_path=off;

server {
    listen 80;
    listen [::]:80;
    server_name chat.example.com;
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name chat.example.com;

    ssl_certificate     /etc/ssl/chat.example.com/fullchain.pem;
    ssl_certificate_key /etc/ssl/chat.example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_timeout 1d;
    ssl_session_cache shared:AntimatterSSL:10m;
    ssl_session_tickets off;

    add_header Strict-Transport-Security "max-age=31536000" always;

    # At least FileSettings.MaxFileSize (100 MB by default).
    client_max_body_size 100M;

    proxy_http_version 1.1;
    proxy_set_header Host              $host;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Upgrade           $http_upgrade;
    proxy_set_header Connection        $connection_upgrade;
    proxy_buffers 256 16k;
    proxy_buffer_size 16k;

    location ~ ^/api/v[0-9]+/(users/)?websocket$ {
        client_body_timeout 60s;
        send_timeout 300s;
        lingering_timeout 5s;
        proxy_connect_timeout 90s;
        proxy_send_timeout 300s;
        proxy_read_timeout 90s;
        proxy_pass http://antimatter;
    }

    location / {
        proxy_read_timeout 600s;
        proxy_cache antimatter_cache;
        proxy_cache_revalidate on;
        proxy_cache_min_uses 2;
        proxy_cache_use_stale timeout;
        proxy_cache_lock on;
        proxy_pass http://antimatter;
    }
}

nginx -t দিয়ে ফাইলটি যাচাই করুন এবং systemctl reload nginx দিয়ে এটি প্রয়োগ করুন। সার্ভার নিজেই X-Content-Type-Options, Referrer-Policy, Permissions-Policy এবং X-Frame-Options পাঠায়; শুধুমাত্র HSTS প্রক্সির দায়িত্বে। HTTPS কাজ করার পর এর max-age বাড়ান, এবং শুধুমাত্র যদি প্রতিটি সাবডোমেইন HTTPS ব্যবহার করে তবে includeSubDomains যোগ করুন।

Docker Compose এবং হোস্টে nginx থাকলে, উপরের upstreamটি পাবলিশ করা পোর্ট 8065-এ পয়েন্ট করে। এটি শুধুমাত্র 127.0.0.1-এ পাবলিশ করুন (HTTP_PORT=127.0.0.1:8065), যাতে কেউ প্রক্সি বাইপাস করতে না পারে।

antimatter-docker রিপোজিটরিতে nginx-কে একটি কন্টেইনারে এবং certbot-এর মাধ্যমে Let's Encrypt ব্যবহার করে একটি সম্পূর্ণ সেটআপ রয়েছে, যা deploy/compose-এ পাওয়া যাবে।

অন্যান্য প্রক্সি

যদি কোনো প্রক্সি উপরের চারটি শর্ত পূরণ করে, তবে তা কাজ করবে। কল অডিও এবং ভিডিও কখনোই প্রক্সির মাধ্যমে যায় না: তারা তাদের নিজস্ব পোর্ট ব্যবহার করে, বিস্তারিত জানতে দেখুন Calls and voice।

প্রক্সির পেছনে ক্লায়েন্ট ঠিকানা

প্রক্সির পেছনে, প্রতিটি রিকোয়েস্ট প্রক্সি থেকে আসার মতো দেখায়। বাস্তব ক্লায়েন্ট ঠিকানা লগ করতে, প্রতি ক্লায়েন্ট অনুযায়ী রেট লিমিট প্রয়োগ করতে এবং IP ফিল্টারিং ব্যবহার করতে, সার্ভারকে বলুন কোন হেডারে ঠিকানা থাকে এবং কোন প্রক্সিগুলোর ওপর সে ভরসা করতে পারে। এই দুটি সেটিংয়ের জন্য System Console-এ কোনো ফিল্ড নেই: সেগুলো config.json-এ বা ভেরিয়েবল দিয়ে সেট করুন।

কী এবং ভেরিয়েবলডিফল্টএটি কী করে
ServiceSettings.TrustedProxyIPHeader, AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADERখালি: সার্ভার সংযোগের ঠিকানা ব্যবহার করেক্লায়েন্টের ঠিকানা বহনকারী হেডারগুলো, যেমন X-Forwarded-For। রিকোয়েসটে উপস্থিত প্রথম হেডারটি ব্যবহার করা হয়।
ServiceSettings.TrustedProxyIPs, AM_SERVICESETTINGS_TRUSTEDPROXYIPSখালিআপনার প্রক্সিগুলোর ঠিকানা বা CIDR রেঞ্জ, যেমন 172.29.71.0/28। হেডারগুলো শুধুমাত্র সেই রিকোয়েস্টগুলোর জন্য গণ্য হয় যা এই ঠিকানাগুলোর একটি থেকে আসে।

একটি ভ্যারিয়েবলে একাধিক মান স্পেস দিয়ে আলাদা করুন: AM_SERVICESETTINGS_TRUSTEDPROXYIPHEADER="X-Forwarded-For X-Real-IP"। সার্ভার এমন একটি কনফিগারেশন প্রত্যাখ্যান করে, যেখানে TrustedProxyIPs-এ এমন একটি এন্ট্রি থাকে যা IP ঠিকানা বা CIDR রেঞ্জ নয়।

সার্ভার ক্লায়েন্টের ঠিকানা কীভাবে খুঁজে পায়

প্রতিটি প্রক্সি রিকোয়েস্ট যে ঠিকানা থেকে পেয়েছে, তা X-Forwarded-For-এর ডান পাশে যোগ করে। ক্লায়েন্ট হেডারটিতে যা পাঠিয়েছিল, তা বাম পাশে থেকে যায়। তাই সার্ভার হেডারটি ডান থেকে পড়ে, আপনার বিশ্বস্ত প্রক্সিগুলোর ঠিকানা বাদ দেয়, এবং প্রথম অন্য ঠিকানাটিকে ক্লায়েন্টের ঠিকানা হিসেবে নেয়। ক্লায়েন্ট নিজের হেডার পাঠিয়ে নিজের ঠিকানা বেছে নিতে পারে না।

  • একটি প্রক্সির পেছনে, TrustedProxyIPHeader একাই সঠিক ঠিকানা দেয়: সার্ভার হেডারের ডানদিকের ঠিকানাটি নেয়। আপনি যতক্ষণ TrustedProxyIPs সেট করেন না, ততক্ষণ স্টার্টআপের সময় এটি একটি ওয়ার্নিং লগ করে। এটি ছাড়া, যে কেউ পোর্ট 8065-এ সরাসরি পৌঁছালে হেডার সেট করতে পারে, তাই এই পোর্টটি শুধুমাত্র 127.0.0.1-এ বা একটি প্রাইভেট নেটওয়ার্কে পাবলিশ করুন।
  • একাধিক প্রক্সির পেছনে, যেমন আপনার নিজের প্রক্সির সামনে একটি CDN বা লোড ব্যালান্সার থাকলে, TrustedProxyIPs-এ তাদের সবাইকে তালিকাভুক্ত করুন। অন্যথায় সার্ভার বাইরের প্রক্সির ঠিকানাটিকে ক্লায়েন্টের ঠিকানা হিসেবে নিয়ে নেবে।
  • প্রক্সিটি হেডারটি তার দেখা ঠিকানা দিয়ে প্রতিস্থাপন করতে পারে, যেমন উপরের nginx উদাহরণটি করে (X-Forwarded-For $remote_addr), অথবা এতে যোগ করতে পারে (nginx-এর $proxy_add_x_forwarded_for)। দুটোই কাজ করে।

কোনো ঠিকানাগুলো তালিকাভুক্ত করতে হবে

Antimatter-এর দৃষ্টিতে প্রক্সির রিকোয়েস্টগুলো যে ঠিকানা থেকে আসে, তা তালিকাভুক্ত করুন।

  • সাইটের compose ফাইল এবং Caddy-এর সাথে এটি ইতিমধ্যে সম্পন্ন: Caddy edge নেটওয়ার্কের মাধ্যমে Antimatter-এ পৌঁছায়, এবং compose ফাইল TrustedProxyIPHeader কে X-Forwarded-For এবং TrustedProxyIPs কে সেই নেটওয়ার্কের রেঞ্জ, EDGE_SUBNET (.env-এ পরিবর্তন না করলে 172.29.71.0/28) হিসেবে সেট করে। যদি EDGE_SUBNET আপনার অন্য কোনো নেটওয়ার্কের সাথে ওভারল্যাপ করে, তবে তা পরিবর্তন করুন।
  • antimatter-docker-এর প্রোডাকশন সেটআপটি তার nginx কন্টেইনারের জন্য FRONTEND_SUBNET ব্যবহার করে একই কাজ করে।
  • হোস্টে nginx এবং Docker-এ Antimatter থাকলে, রিকোয়েস্টগুলো সাধারণত compose প্রজেক্টের নেটওয়ার্কের গেটওয়ে ঠিকানা থেকে Antimatter-এ পৌঁছায় (docker network inspect দিয়ে তা দেখা যায়)। compose.override.yaml-এ AM_SERVICESETTINGS_TRUSTEDPROXYIPS কে সেই ঠিকানা হিসেবে সেট করুন।
  • Docker ছাড়া, একই হোস্টে nginx থাকলে এটি 127.0.0.1 (nginx IPv6-এর মাধ্যমে সংযুক্ত হলে ::1)।

প্রক্সি ছাড়া TLS

সার্ভার নিজেও HTTPS সার্ভ করতে পারে, সিস্টেম কনসোল › এনভাইরনমেন্ট › ওয়েব সার্ভার-এ: কানেকশন সিকিউরিটি TLS-তে সেট করুন (ServiceSettings.ConnectionSecurity), সাথে TLS সার্টিফিকেট ফাইল এবং TLS কী ফাইল (ServiceSettings.TLSCertFile, ServiceSettings.TLSKeyFile), অথবা Let's Encrypt ব্যবহার করুন (ServiceSettings.UseLetsEncrypt)। এরপর সার্ভারকে পোর্ট 443-এ লিসেন করতে হবে (লিসেন ঠিকানা, ServiceSettings.ListenAddress, ডিফল্ট :8065), এবং ServiceSettings.Forward80To443 পোর্ট 80-কে রিডাইরেক্ট করে। রিভার্স প্রক্সি চালনা এবং রিনিউ করা সহজ, এবং এই গাইডেও তাই ধরা হয়েছে।

সার্ভার টাইমআউট এবং রিকোয়েস্ট সাইজ

সার্ভারের নিজস্ব ওয়েব সার্ভারের সেটিংস, সিস্টেম কনসোল › এনভাইরনমেন্ট › ওয়েব সার্ভার-এ:

সেটিংকীডিফল্ট
লিসেন ঠিকানাServiceSettings.ListenAddress:8065
রিড টাইমআউটServiceSettings.ReadTimeout৩০০ সেকেন্ড
রাইট টাইমআউটServiceSettings.WriteTimeout৩০০ সেকেন্ড
আইডল টাইমআউট (System Console-এ কোনো ফিল্ড নেই)ServiceSettings.IdleTimeout৬০ সেকেন্ড
সর্বোচ্চ পেইলোড সাইজ (বাইট)ServiceSettings.MaximumPayloadSizeBytesদেখুন Security

সাধারণ রিকোয়েস্টের জন্য প্রক্সির নিজস্ব টাইমআউটগুলো কমপক্ষে এই মানের সমান রাখুন, এবং বডি সাইজ কমপক্ষে সর্বোচ্চ ফাইল সাইজ রাখুন।