Compare commits

...

11 Commits

Author SHA1 Message Date
Egor Savkin eb7a22729a Prototype mail router
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 17:23:37 +08:00
Egor Savkin a6a77f56e1 Remove request rate restriction and remove proxy protocol
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Egor Savkin d337612ccc Limit connections and redirect www to canonical
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Egor Savkin 3f3a1e62e6 Move away from automated script
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Egor Savkin bc3f4608d5 Postfix instead of nginx streams
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Egor Savkin fbb6a9b570 Remove imap and pop3 ports proxy
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Egor Savkin 4cbbb8d945 Add configuration for the m-labs-intl
Signed-off-by: Egor Savkin <es@m-labs.hk>
2024-08-19 10:57:36 +08:00
Sébastien Bourdeauducq 6dc8214102 nixbld/backup: include gitea DB dump 2024-08-17 18:26:46 +08:00
Sébastien Bourdeauducq a6b216bb87 nixbld/gitea: move to postgresql 2024-08-17 18:18:56 +08:00
Sébastien Bourdeauducq 6e21a95ba8 nixbld/named: add qnetp slave DNS for m-labs-intl.com 2024-08-15 19:52:42 +08:00
Sébastien Bourdeauducq d08186a27a nixbld/named: enable CAA for m-labs-intl.com 2024-08-14 11:52:25 +08:00
15 changed files with 755 additions and 2 deletions

43
m-labs-intl/danted.conf Normal file
View File

@ -0,0 +1,43 @@
logoutput: syslog
user.privileged: root
user.unprivileged: nobody
# The listening network interface or address.
internal: 5.78.86.156 port=2025
internal: 2a01:4ff:1f0:83de::1 port = 2025
# The proxying network interface or address.
external: eth0
# socks-rules determine what is proxied through the external interface.
socksmethod: none
# client-rules determine who can connect to the internal interface.
clientmethod: none
client pass {
from: 94.190.212.123/32 to: 0.0.0.0/0
}
socks pass {
from: 94.190.212.123/32 to: 0.0.0.0/0
}
client pass {
from: 202.77.7.238/32 to: 0.0.0.0/0
}
socks pass {
from: 202.77.7.238/32 to: 0.0.0.0/0
}
client pass {
from: 2001:470:18:390::2/128 to: 0.0.0.0/0
}
socks pass {
from: 2001:470:18:390::2/128 to: 0.0.0.0/0
}
client pass {
from: 2001:470:f891:1:5999:5529:5d:f71d/128 to: 0.0.0.0/0
}
socks pass {
from: 2001:470:f891:1:5999:5529:5d:f71d/128 to: 0.0.0.0/0
}

View File

@ -0,0 +1,81 @@
upstream rfq_server {
server 127.0.0.1:5000;
}
server {
limit_conn addr 5;
root /var/www/m-labs-intl.com/html;
index index.html index.htm index.nginx-debian.html;
server_name m-labs-intl.com;
location / {
try_files $uri $uri/ =404;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name www.m-labs-intl.com;
return 301 https://m-labs-intl.com$request_uri;
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name hooks.m-labs-intl.com;
limit_conn addr 5;
location /rfq {
proxy_pass http://rfq_server/rfq;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 30;
proxy_connect_timeout 30;
proxy_send_timeout 30;
}
location / {
return 418;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/m-labs-intl.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/m-labs-intl.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
limit_conn addr 5;
if ($host = m-labs-intl.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = www.m-labs-intl.com) {
return 301 https://m-labs-intl.com$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name m-labs-intl.com www.m-labs-intl.com hooks.m-labs-intl.com;
return 301 https://$host$request_uri;
}

0
m-labs-intl/mail.secret Normal file
View File

63
m-labs-intl/main.cf Normal file
View File

@ -0,0 +1,63 @@
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6
# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = mail.m-labs-intl.com
mydomain = m-labs-intl.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $mydomain
#mydestination = $myhostname, m-labs-intl.com, localhost.localdomain, localhost
mydestination =
relayhost = mail.m-labs.hk
#relay_domains = $mydomain
local_transport = error:local delivery disabled
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_alias_domains = $mydomain m-labs.hk
# DKIM
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

90
m-labs-intl/nginx.conf Normal file
View File

@ -0,0 +1,90 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
# Rate limiting
limit_conn_zone $binary_remote_addr zone=addr:10m;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
stream {
# Upstream mail servers
upstream smtp_backend {
server mail.m-labs.hk:25;
}
upstream submission_backend {
server mail.m-labs.hk:587;
}
# SMTP
server {
listen 25;
proxy_protocol on;
proxy_pass smtp_backend;
}
# Submission (Authenticated SMTP)
server {
listen 587;
proxy_protocol on;
proxy_pass submission_backend;
}
}

32
m-labs-intl/opendkim Normal file
View File

@ -0,0 +1,32 @@
# NOTE: This is a legacy configuration file. It is not used by the opendkim
# systemd service. Please use the corresponding configuration parameters in
# /etc/opendkim.conf instead.
#
# Previously, one would edit the default settings here, and then execute
# /lib/opendkim/opendkim.service.generate to generate systemd override files at
# /etc/systemd/system/opendkim.service.d/override.conf and
# /etc/tmpfiles.d/opendkim.conf. While this is still possible, it is now
# recommended to adjust the settings directly in /etc/opendkim.conf.
#
#DAEMON_OPTS=""
# Change to /var/spool/postfix/run/opendkim to use a Unix socket with
# postfix in a chroot:
#RUNDIR=/var/spool/postfix/run/opendkim
RUNDIR=/run/opendkim
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in opendkim.conf
# default:
SOCKET=local:$RUNDIR/opendkim.sock
# listen on all interfaces on port 54321:
#SOCKET=inet:54321
# listen on loopback on port 12345:
#SOCKET=inet:12345@localhost
# listen on 192.0.2.1 on port 12345:
#SOCKET=inet:12345@192.0.2.1
USER=opendkim
GROUP=opendkim
PIDFILE=$RUNDIR/$NAME.pid
EXTRAAFTER=
SOCKET="inet:8891@localhost"

57
m-labs-intl/opendkim.conf Normal file
View File

@ -0,0 +1,57 @@
# This is a basic configuration for signing and verifying. It can easily be
# adapted to suit a basic installation. See opendkim.conf(5) and
# /usr/share/doc/opendkim/examples/opendkim.conf.sample for complete
# documentation of available configuration parameters.
Syslog yes
SyslogSuccess yes
#LogWhy no
# Common signing and verification parameters. In Debian, the "From" header is
# oversigned, because it is often the identity key used by reputation systems
# and thus somewhat security sensitive.
Canonicalization relaxed/simple
#Mode sv
#SubDomains no
OversignHeaders From
# Signing domain, selector, and key (required). For example, perform signing
# for domain "example.com" with selector "2020" (2020._domainkey.example.com),
# using the private key stored in /etc/dkimkeys/example.private. More granular
# setup options can be found in /usr/share/doc/opendkim/README.opendkim.
#Domain example.com
#Selector 2020
#KeyFile /etc/dkimkeys/example.private
# In Debian, opendkim runs as user "opendkim". A umask of 007 is required when
# using a local socket with MTAs that access the socket as a non-privileged
# user (for example, Postfix). You may need to add user "postfix" to group
# "opendkim" in that case.
UserID opendkim
UMask 007
# Socket for the MTA connection (required). If the MTA is inside a chroot jail,
# it must be ensured that the socket is accessible. In Debian, Postfix runs in
# a chroot in /var/spool/postfix, therefore a Unix socket would have to be
# configured as shown on the last line below.
Socket local:/run/opendkim/opendkim.sock
#Socket inet:8891@localhost
#Socket inet:8891
#Socket local:/var/spool/postfix/opendkim/opendkim.sock
PidFile /run/opendkim/opendkim.pid
# Hosts for which to sign rather than verify, default is 127.0.0.1. See the
# OPERATION section of opendkim(8) for more information.
#InternalHosts 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12
# The trust anchor enables DNSSEC. In Debian, the trust anchor file is provided
# by the package dns-root-data.
TrustAnchorFile /usr/share/dns/root.key
#Nameservers 127.0.0.1
Domain m-labs-intl.com
KeyFile /etc/postfix/dkim.key
Selector mail
SOCKET inet:8891@localhost

12
m-labs-intl/rfq.service Normal file
View File

@ -0,0 +1,12 @@
[Unit]
Description=RFQ service
After=network.target
[Service]
Type=simple
User=rfqserver
ExecStart=/home/rfqserver/runrfq.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target

14
m-labs-intl/runrfq.sh Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env bash
export FLASK_DEBUG=0
export FLASK_MAIL_SERVER=mail.m-labs.hk
export FLASK_MAIL_PORT=465
export FLASK_MAIL_USE_SSL=True
export FLASK_MAIL_USERNAME=sysop-intl@m-labs-intl.com
export FLASK_MAIL_PASSWORD_FILE=/home/rfqserver/mail.secret
export FLASK_MAIL_RECIPIENT=sales@m-labs.hk
export FLASK_MAIL_SENDER=sysop-intl@m-labs-intl.com
cd /home/rfqserver/web2019/server
source venv/bin/activate
python3 -m flask --app rfq run --port=5000

71
m-labs-intl/setup.md Normal file
View File

@ -0,0 +1,71 @@
# Setup m-labs-intl.com server
```shell
apt install git nginx-full python3 python3.12-venv python3-pip dante-server
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
useradd -m rfqserver
useradd -m zolaupd
cp m-labs-intl.com /etc/nginx/sites-available/
cp nginx.conf /etc/nginx/
ln -s /etc/nginx/sites-available/m-labs-intl.com /etc/nginx/sites-enabled/
cp danted.conf /etc/
mkdir -p /var/www/m-labs-intl.com/html
chown -R zolaupd /var/www/m-labs-intl.com/
cp runrfq.sh /home/rfqserver/
cp mail.secret /home/rfqserver/
chown rfqserver /home/rfqserver/runrfq.sh
chmod +x /home/rfqserver/runrfq.sh
chown rfqserver /home/rfqserver/mail.secret
sudo -u zolaupd sh -c '
cd /home/zolaupd;
mkdir /home/zolaupd/.ssh;
echo -n "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP1OJJM8g/1ffxDjN31XKEfGmrYaW03lwpyTa1UGWqVx
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF6R6XK0IiuAKxVKvSABm4m9bfOlvfJcMvTpjenuXUPv" > /home/zolaupd/.ssh/authorized_keys
chmod 700 .ssh/
chmod 600 .ssh/authorized_keys
'
sudo -u rfqserver sh -c '
cd /home/rfqserver;
git clone https://git.m-labs.hk/M-Labs/web2019.git;
cd web2019;
python3 -m venv ./venv;
source venv/bin/activate;
pip install -r requirements.txt;
'
cp rfq.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable rfq.service
systemctl start rfq.service
systemctl enable danted.service
service nginx restart
service danted restart
certbot --nginx
service nginx restart
ufw default deny
ufw allow from 94.190.212.123
ufw allow from 2001:470:f891:1:5999:5529:5d:f71d
ufw allow from 202.77.7.238
ufw allow from 2001:470:18:390::2
ufw allow "Nginx HTTP"
ufw allow "Nginx HTTPS"
ufw limit OpenSSH
ufw default allow outgoing
ufw limit 25/tcp
ufw limit 587/tcp
ufw show added
ufw enable
```

278
m-labs-intl/smtp_router.py Normal file
View File

@ -0,0 +1,278 @@
import asyncio
import email
import logging
from smtplib import SMTP as SMTPClient
from typing import Dict
from aiosmtpd.proxy_protocol import ProxyData
from python_socks.sync import Proxy
import os
import ssl
from aiosmtpd.controller import Controller
from aiosmtpd.smtp import Envelope, Session, SMTP
from email.message import Message
import dkim
import spf
from functools import lru_cache
import dns.resolver
PROXY = Proxy.from_url('socks5://5.78.86.156:2025')
END_HOST = "localhost"
END_PORT = 25
PROXY_SMTP_HOST = "*"
PROXY_SMTP_PORT = 2025
END_SMTP_HOST = "*"
END_SMTP_PORT = 3025
GENERIC_SMTP_HOST = "*"
GENERIC_SMTP_PORT = 25
log = logging.getLogger("smtphandler")
VALID_PROXY_ADDRS = {"5.78.86.156", "2a01:4ff:1f0:83de::1", "m-labs-intl.com", "mail.m-labs-intl.com"}
VALID_END_ADDRS = {"localhost", "127.0.0.1"}
VALID_RECEPIENTS = {"m-labs.hk", "m-labs.ph", "m-labs-intl.com", "193thz.com", "malloctech.fr"}
@lru_cache(maxsize=256)
def get_mx(domain):
records = dns.resolver.resolve(domain, "MX")
if not records:
return None
result = max(records, key=lambda r: r.preference)
return str(result.exchange)
class ProxiedSMTP(SMTPClient):
def _get_socket(self, host, port, timeout):
return PROXY.connect(dest_host=host, dest_port=port, timeout=timeout)
class GenericMailServer:
"""
Accepts mail from everywhere, and passes it to the real SMTP server, after proper SPF and DKIM checks.
"""
async def handle_MAIL(self,
server: SMTP,
session: Session,
envelope: Envelope,
address: str,
mail_options: list):
ip = session.peer[0]
result, description = spf.check2(ip, address, session.host_name)
valid_spf = result == 'pass'
envelope.spf = valid_spf
log.info("SPF: %s, %s", result, description)
if not valid_spf:
return '550 SPF validation failed'
envelope.mail_from = address
envelope.mail_options.extend(mail_options)
return '250 OK'
async def handle_RCPT(self,
server: SMTP,
session: Session,
envelope: Envelope,
address: str,
rcpt_options: list):
if address.split("@")[1] not in VALID_RECEPIENTS:
return '550 not relaying to that domain'
log.debug("Handle RCPT for %s", address)
envelope.rcpt_tos.append(address)
return '250 OK'
async def handle_DATA(self,
server: SMTP,
session: Session,
envelope: Envelope):
valid_dkim = dkim.verify(envelope.content)
envelope.dkim = valid_dkim
log.info("DKIM: %s", valid_dkim)
message: Message = email.message_from_bytes(envelope.content)
if not valid_dkim:
return '550 DKIM validation failed'
log.info('Message: %s', message)
try:
with SMTPClient(END_HOST, END_PORT) as client:
client.sendmail(
from_addr=envelope.mail_from,
to_addrs=envelope.rcpt_tos,
msg=envelope.original_content
)
except BaseException as e:
print(e)
return '500 Could not process your message'
return '250 Message accepted for delivery'
class EndMailServer:
"""
Accepts mail only from end server. Checks if mail is signed to be from proxy, and sends to proxy if needed.
SPF and DKIM needs to be already included.
"""
async def handle_DATA(self,
server: SMTP,
session: Session,
envelope: Envelope):
ip = session.peer[0]
if ip not in VALID_END_ADDRS:
return "521 Server doesn't accept mail"
message: Message = email.message_from_bytes(envelope.content)
log.info('Message: %s', message)
mx_rcpt: Dict[str, list[str]] = {}
for rcpt in envelope.rcpt_tos:
_, _, domain = rcpt.partition("@")
mx = get_mx(domain)
if mx is None:
continue
mx_rcpt.setdefault(mx, []).append(rcpt)
try:
for mx, rcpts in mx_rcpt.items():
if envelope.mail_from in VALID_PROXY_ADDRS:
with ProxiedSMTP(mx, 25) as client:
client.sendmail(
from_addr=envelope.mail_from,
to_addrs=rcpts,
msg=envelope.original_content
)
else:
with SMTPClient(mx, 25) as client:
client.sendmail(
from_addr=envelope.mail_from,
to_addrs=rcpts,
msg=envelope.original_content
)
except BaseException as e:
print(e)
return '500 Could not process your message'
return '250 Message accepted for delivery'
class ProxyMailServer:
"""
Accepts mail only from proxy server, and passes it to the real SMTP server, after proper SPF and DKIM checks.
"""
async def handle_PROXY(self, server: SMTP, session: Session, envelope: Envelope, proxy_data: ProxyData):
ip = session.peer[0]
envelope.proxy_data = proxy_data
return ip in VALID_PROXY_ADDRS
async def handle_MAIL(self,
server: SMTP,
session: Session,
envelope: Envelope,
address: str,
mail_options: list):
ip = envelope.proxy_data.src_addr
result, description = spf.check2(ip, address, session.host_name)
valid_spf = result == 'pass'
envelope.spf = valid_spf
log.info("SPF: %s, %s", result, description)
if not valid_spf:
return '550 SPF validation failed'
envelope.mail_from = address
envelope.mail_options.extend(mail_options)
return '250 OK'
async def handle_RCPT(self,
server: SMTP,
session: Session,
envelope: Envelope,
address: str,
rcpt_options: list):
if address.split("@")[1] not in VALID_RECEPIENTS:
return '550 not relaying to that domain'
log.debug("Handle RCPT for %s", address)
envelope.rcpt_tos.append(address)
return '250 OK'
async def handle_DATA(self,
server: SMTP,
session: Session,
envelope: Envelope):
valid_dkim = dkim.verify(envelope.content)
envelope.dkim = valid_dkim
log.info("DKIM: %s", valid_dkim)
message: Message = email.message_from_bytes(envelope.content)
if not valid_dkim:
return '550 DKIM validation failed'
log.info('Message: %s', message)
try:
with SMTPClient(END_HOST, END_PORT) as client:
client.sendmail(
from_addr=envelope.mail_from,
to_addrs=envelope.rcpt_tos,
msg=envelope.original_content
)
except BaseException as e:
print(e)
return '500 Could not process your message'
return '250 Message accepted for delivery'
if __name__ == '__main__':
host = os.getenv('SMTP_HOST', '*')
port = int(os.getenv('SMTP_PORT', '25'))
accept_host = os.getenv('ACCEPT_HOST')
ssl_keys = os.getenv('SSL_KEYS')
loop = asyncio.get_event_loop()
end_handler = EndMailServer()
proxy_handler = ProxyMailServer()
generic_handler = GenericMailServer()
ssl_context = None
if ssl_keys:
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_context.load_cert_chain(ssl_keys + '.crt', ssl_keys + '.key')
generic_controller = Controller(GenericMailServer, hostname=GENERIC_SMTP_HOST, port=GENERIC_SMTP_PORT)
generic_controller.factory = lambda: SMTP(GenericMailServer, enable_SMTPUTF8=True, tls_context=ssl_context)
generic_controller.start()
log.info("Generic SMTP server started on %s:%s", GENERIC_SMTP_HOST, GENERIC_SMTP_PORT)
end_controller = Controller(EndMailServer, hostname=END_SMTP_HOST, port=END_SMTP_PORT)
end_controller.factory = lambda: SMTP(EndMailServer, enable_SMTPUTF8=True)
end_controller.start()
log.info("End SMTP server started on %s:%s", END_SMTP_HOST, END_SMTP_PORT)
proxy_controller = Controller(ProxyMailServer, hostname=PROXY_SMTP_HOST, port=PROXY_SMTP_PORT)
proxy_controller.factory = lambda: SMTP(ProxyMailServer, enable_SMTPUTF8=True, tls_context=ssl_context)
proxy_controller.start()
log.info("Proxy SMTP server started on %s:%s", PROXY_SMTP_HOST, PROXY_SMTP_PORT)
try:
loop.run_forever()
except KeyboardInterrupt:
print("Shutting down")
finally:
generic_controller.stop()
end_controller.stop()
proxy_controller.stop()
loop.stop()
loop.close()

1
m-labs-intl/virtual Normal file
View File

@ -0,0 +1 @@
es@m-labs-intl.com es@m-labs.hk

View File

@ -26,9 +26,10 @@ let
${config.services.mysql.package}/bin/mysqldump --user=root --single-transaction flarum > flarum.sql ${config.services.mysql.package}/bin/mysqldump --user=root --single-transaction flarum > flarum.sql
${config.services.postgresql.package}/bin/pg_dump mattermost > mattermost.sql ${config.services.postgresql.package}/bin/pg_dump mattermost > mattermost.sql
${config.services.postgresql.package}/bin/pg_dump rt5 > rt.sql ${config.services.postgresql.package}/bin/pg_dump rt5 > rt.sql
${config.services.postgresql.package}/bin/pg_dump gitea > gitea.sql
exec 6< /etc/nixos/secret/backup-passphrase exec 6< /etc/nixos/secret/backup-passphrase
${pkgs.gnutar}/bin/tar cf - ${lib.concatMapStringsSep " " (p: "--exclude \"${p}\"") excludePaths} /etc/nixos /var/vmail /var/lib/hedgedoc /var/lib/gitea /var/lib/afws /var/lib/mattermost/data /var/www/193thz flarum.sql mattermost.sql rt.sql | \ ${pkgs.gnutar}/bin/tar cf - ${lib.concatMapStringsSep " " (p: "--exclude \"${p}\"") excludePaths} /etc/nixos /var/vmail /var/lib/hedgedoc /var/lib/gitea /var/lib/afws /var/lib/mattermost/data /var/www/193thz flarum.sql mattermost.sql rt.sql gitea.sql | \
${pkgs.bzip2}/bin/bzip2 | \ ${pkgs.bzip2}/bin/bzip2 | \
${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-fd 6 ${pkgs.gnupg}/bin/gpg --symmetric --batch --passphrase-fd 6
''; '';

View File

@ -375,10 +375,14 @@ in
notify explicit; notify explicit;
also-notify { also-notify {
216.218.130.2; # ns1.he.net 216.218.130.2; # ns1.he.net
213.239.220.50; # ns1.qnetp.net
88.198.32.245; # new qnetp
}; };
''; '';
slaves = [ slaves = [
"216.218.133.2" "2001:470:600::2" # slave.dns.he.net "216.218.133.2" "2001:470:600::2" # slave.dns.he.net
"213.239.220.50" "2a01:4f8:a0:7041::1" # ns1.qnetp.net
"88.198.32.245" # new qnetp
]; ];
}; };
"200-29.98.206.103.in-addr.arpa" = { "200-29.98.206.103.in-addr.arpa" = {
@ -773,6 +777,10 @@ in
services.gitea = { services.gitea = {
enable = true; enable = true;
appName = "M-Labs Git"; appName = "M-Labs Git";
database = {
type = "postgres";
socket = "/run/postgresql";
};
mailerPasswordFile = "/etc/nixos/secret/mailerpassword"; mailerPasswordFile = "/etc/nixos/secret/mailerpassword";
settings = { settings = {
server = { server = {

View File

@ -1,7 +1,7 @@
$TTL 7200 $TTL 7200
@ SOA ns.m-labs-intl.com. sb.m-labs.hk. ( @ SOA ns.m-labs-intl.com. sb.m-labs.hk. (
2024081402 2024081503
7200 7200
3600 3600
86400 86400
@ -10,12 +10,14 @@ $TTL 7200
NS ns.m-labs-intl.com. NS ns.m-labs-intl.com.
NS ns1.he.net. NS ns1.he.net.
NS ns1.qnetp.net.
A 5.78.86.156 A 5.78.86.156
AAAA 2a01:4ff:1f0:83de::1 AAAA 2a01:4ff:1f0:83de::1
MX 10 mail.m-labs-intl.com. MX 10 mail.m-labs-intl.com.
TXT "v=spf1 mx -all" TXT "v=spf1 mx -all"
TXT "google-site-verification=BlQd5_5wWW7calKC7bZA0GdoxR8-zj4gwJEg9sGJ3l8" TXT "google-site-verification=BlQd5_5wWW7calKC7bZA0GdoxR8-zj4gwJEg9sGJ3l8"
CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1768317117"
ns A 94.190.212.123 ns A 94.190.212.123
ns AAAA 2001:470:18:390::2 ns AAAA 2001:470:18:390::2