Merge improvements/fork-harvest into main
Fork-harvest brings: the ip-api.com geo fix, credential bundle scan, mock gateways out of production, JIT compiler dropped (1.55->1.04 MB), host hardening, provider-agnostic identity + VK/Yandex + account linking, and the backend contracts consolidated into one BACKEND-INTEGRATION.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> # Conflicts: # docs/backend/BACKEND-HANDOFF.md # docs/backend/TRACK-S-SECURITY-RBAC-CONTRACT.md
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
# Fails the build if a production bundle contains anything that should only
|
||||
# ever exist server-side.
|
||||
#
|
||||
# It also fails on mock gateway code, for the same reason in a different
|
||||
# register: a production build that can reach a *LocalGateway is a production
|
||||
# build that can serve seeded fixtures as if they were real data. Those used to
|
||||
# ship - a fixture string from partner-hierarchy-local.gateway.ts was present in
|
||||
# a production bundle on 2026-08-21 - because naming both classes in a token
|
||||
# factory kept both reachable no matter what the flag said.
|
||||
#
|
||||
# Why this exists: the storefront used to send provider payment credentials
|
||||
# from the browser - an `authorization-key` header, a `userid-value` header,
|
||||
# and a hardcoded partner ID literal compiled into the bundle. That code is
|
||||
@@ -30,6 +37,8 @@ PATTERNS=(
|
||||
"private key block|BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY"
|
||||
"aws access key|AKIA[0-9A-Z]{16}"
|
||||
"telegram bot token|[0-9]{8,10}:AA[0-9A-Za-z_-]{33}"
|
||||
"mock gateway class|[A-Za-z]+LocalGateway"
|
||||
"mock gateway fixture|ptr_local|customer_vk_mock"
|
||||
)
|
||||
|
||||
failed=0
|
||||
@@ -49,7 +58,9 @@ done
|
||||
|
||||
if [[ $failed -ne 0 ]]; then
|
||||
echo >&2
|
||||
echo "A credential reached the browser bundle. Move it behind the API." >&2
|
||||
echo "Something reached the browser bundle that should not have." >&2
|
||||
echo "Credentials belong behind the API; mock gateways belong in dev-only" >&2
|
||||
echo "providers swapped out by angular.json fileReplacements." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -128,6 +128,90 @@ ufw allow 80/tcp >/dev/null
|
||||
ufw allow 443/tcp >/dev/null
|
||||
ufw --force enable >/dev/null
|
||||
|
||||
# FH-D.3. ufw alone leaves SSH open to unlimited password guessing and leaves
|
||||
# the kernel on defaults that are wrong for an internet-facing host. All three
|
||||
# blocks below are drop-in files, so a re-run overwrites its own config and
|
||||
# never edits a distro file in place.
|
||||
|
||||
echo "==> sshd hardening"
|
||||
cat > /etc/ssh/sshd_config.d/10-marketplaces-hardening.conf <<'SSHD'
|
||||
# Both accounts on this host are key-only by construction (the deploy user is
|
||||
# created with no password at all), so password auth can only ever succeed for
|
||||
# a credential nobody intended to exist.
|
||||
PasswordAuthentication no
|
||||
KbdInteractiveAuthentication no
|
||||
PermitEmptyPasswords no
|
||||
PermitRootLogin prohibit-password
|
||||
X11Forwarding no
|
||||
AllowAgentForwarding no
|
||||
MaxAuthTries 3
|
||||
LoginGraceTime 30
|
||||
ClientAliveInterval 300
|
||||
ClientAliveCountMax 2
|
||||
SSHD
|
||||
# Validate before reloading: a bad sshd config that takes effect on a remote
|
||||
# box is how people lock themselves out permanently.
|
||||
if sshd -t; then
|
||||
systemctl reload ssh 2>/dev/null || systemctl reload sshd
|
||||
else
|
||||
echo "sshd config test FAILED - removing the drop-in and leaving sshd as it was" >&2
|
||||
rm -f /etc/ssh/sshd_config.d/10-marketplaces-hardening.conf
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "==> fail2ban"
|
||||
apt-get install -y -qq fail2ban
|
||||
cat > /etc/fail2ban/jail.d/marketplaces.local <<'F2B'
|
||||
[DEFAULT]
|
||||
backend = systemd
|
||||
findtime = 10m
|
||||
bantime = 1h
|
||||
maxretry = 5
|
||||
|
||||
[sshd]
|
||||
enabled = true
|
||||
|
||||
[nginx-http-auth]
|
||||
enabled = true
|
||||
|
||||
[nginx-bad-request]
|
||||
enabled = true
|
||||
F2B
|
||||
systemctl enable --now fail2ban
|
||||
systemctl restart fail2ban
|
||||
|
||||
echo "==> kernel hardening"
|
||||
cat > /etc/sysctl.d/99-marketplaces-hardening.conf <<'SYSCTL'
|
||||
# Ignore ICMP redirects and source routing: this host has one gateway and
|
||||
# nothing upstream should be rewriting its routing table.
|
||||
net.ipv4.conf.all.accept_redirects = 0
|
||||
net.ipv4.conf.default.accept_redirects = 0
|
||||
net.ipv6.conf.all.accept_redirects = 0
|
||||
net.ipv6.conf.default.accept_redirects = 0
|
||||
net.ipv4.conf.all.send_redirects = 0
|
||||
net.ipv4.conf.default.send_redirects = 0
|
||||
net.ipv4.conf.all.accept_source_route = 0
|
||||
net.ipv6.conf.all.accept_source_route = 0
|
||||
|
||||
# Reverse-path filtering and martian logging.
|
||||
net.ipv4.conf.all.rp_filter = 1
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
net.ipv4.conf.all.log_martians = 1
|
||||
|
||||
# SYN flood resistance.
|
||||
net.ipv4.tcp_syncookies = 1
|
||||
net.ipv4.tcp_max_syn_backlog = 2048
|
||||
net.ipv4.tcp_synack_retries = 2
|
||||
|
||||
# No IP forwarding: this is a web server, not a router.
|
||||
net.ipv4.ip_forward = 0
|
||||
|
||||
# Restrict kernel pointer and dmesg exposure to unprivileged users.
|
||||
kernel.kptr_restrict = 2
|
||||
kernel.dmesg_restrict = 1
|
||||
SYSCTL
|
||||
sysctl --quiet --system
|
||||
|
||||
echo "==> nginx config test"
|
||||
nginx -t
|
||||
systemctl enable --now nginx
|
||||
|
||||
Reference in New Issue
Block a user