Compare commits
24
Commits
c075cf282b
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
609da6b6bc | ||
|
|
402499d109 | ||
|
|
1389d5faa3 | ||
|
|
59e6c5c6a1 | ||
|
|
4f8a975337 | ||
|
|
c251867f05 | ||
|
|
b06cddca4a | ||
|
|
19aface599 | ||
|
|
528a109d53 | ||
|
|
97b635e8c6 | ||
|
|
99e438d9c5 | ||
|
|
8e850f05c4 | ||
|
|
6c2a4fc9d2 | ||
|
|
3e92f68d78 | ||
|
|
2050129062 | ||
|
|
a6148753ca | ||
|
|
d02989f1a7 | ||
|
|
6e317eb05a | ||
|
|
4e114edb89 | ||
|
|
49123c08b3 | ||
|
|
539b5b8320 | ||
|
|
39df52aab7 | ||
|
|
b326911478 | ||
|
|
8242325ffd |
+45
-1
@@ -25,5 +25,49 @@
|
|||||||
"filePattern": ".claude/skills/deploy-workflow.md",
|
"filePattern": ".claude/skills/deploy-workflow.md",
|
||||||
"description": "CI/CD pipeline, Docker patterns, deployment guide"
|
"description": "CI/CD pipeline, Docker patterns, deployment guide"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"hooks": {
|
||||||
|
"PreToolUse": [
|
||||||
|
{
|
||||||
|
"matcher": "",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "serena-hooks remind --client=claude-code"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matcher": "mcp__serena__*",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "serena-hooks auto-approve --client=claude-code"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SessionStart": [
|
||||||
|
{
|
||||||
|
"matcher": "",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "serena-hooks activate --client=claude-code"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SessionEnd": [
|
||||||
|
{
|
||||||
|
"matcher": "",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "serena-hooks cleanup --client=claude-code"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v7
|
||||||
- uses: DeterminateSystems/determinate-nix-action@main
|
- uses: DeterminateSystems/determinate-nix-action@main
|
||||||
- uses: DeterminateSystems/flakehub-push@main
|
- uses: DeterminateSystems/flakehub-push@main
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ concurrency:
|
|||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
id-token: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
VPS_HOST: ${{ secrets.VPS_HOST }}
|
VPS_HOST: ${{ secrets.VPS_HOST }}
|
||||||
@@ -44,6 +45,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Cache Nix
|
- name: Cache Nix
|
||||||
uses: DeterminateSystems/magic-nix-cache-action@v14
|
uses: DeterminateSystems/magic-nix-cache-action@v14
|
||||||
|
with:
|
||||||
|
use-flakehub: false
|
||||||
|
|
||||||
- name: Build ${{ matrix.service }}
|
- name: Build ${{ matrix.service }}
|
||||||
id: build
|
id: build
|
||||||
@@ -79,3 +82,22 @@ jobs:
|
|||||||
ssh "$VPS_USER@$VPS_HOST" "sudo systemctl restart ${{ matrix.service }}" || echo " ⚠️ restart failed (may not be enabled yet)"
|
ssh "$VPS_USER@$VPS_HOST" "sudo systemctl restart ${{ matrix.service }}" || echo " ⚠️ restart failed (may not be enabled yet)"
|
||||||
|
|
||||||
echo "✅ ${{ matrix.service }} deployed"
|
echo "✅ ${{ matrix.service }} deployed"
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
# Bersihkan sampah Nix di VPS SETELAH deploy: hapus generasi profile lama
|
||||||
|
# + nix store gc. Profil yang sedang dipakai tidak disentuh.
|
||||||
|
needs: build-and-deploy
|
||||||
|
if: always()
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Nix GC on VPS
|
||||||
|
env:
|
||||||
|
VPS_HOST: ${{ secrets.VPS_HOST }}
|
||||||
|
VPS_USER: ${{ secrets.VPS_USER }}
|
||||||
|
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "$SSH_KEY" > ~/.ssh/id_ed25519
|
||||||
|
chmod 600 ~/.ssh/id_ed25519
|
||||||
|
ssh-keyscan -H "$VPS_HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
ssh "$VPS_USER@$VPS_HOST" "sudo /usr/local/bin/nix-gc-vps.sh" || echo "⚠️ Nix GC gagal (non-fatal)"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ node_modules
|
|||||||
.turbo/
|
.turbo/
|
||||||
# IDEs and editors
|
# IDEs and editors
|
||||||
/.idea
|
/.idea
|
||||||
|
.serena/
|
||||||
.project
|
.project
|
||||||
.classpath
|
.classpath
|
||||||
.c9/
|
.c9/
|
||||||
|
|||||||
+1
-1
Submodule apps/hub updated: 62966fd7cf...c891439857
@@ -61,7 +61,7 @@
|
|||||||
# ── Fetch submodule source ──
|
# ── Fetch submodule source ──
|
||||||
submoduleSrc = name: builtins.fetchGit {
|
submoduleSrc = name: builtins.fetchGit {
|
||||||
url = submoduleRepos.${name};
|
url = submoduleRepos.${name};
|
||||||
rev = if name == "hub" then "62966fd7cf457982a0fc3b55198f93e50fab6194"
|
rev = if name == "hub" then "a90d0c43336a5f000b5856003d2293c420e7d595"
|
||||||
else if name == "scraper" then "62aa5b0e52859afe3ba9de1c7b11cfe2dacf6c2c"
|
else if name == "scraper" then "62aa5b0e52859afe3ba9de1c7b11cfe2dacf6c2c"
|
||||||
else if name == "tools" then "3956b90c3ce39ffa7ffba8084937f20e11364d6b"
|
else if name == "tools" then "3956b90c3ce39ffa7ffba8084937f20e11364d6b"
|
||||||
else if name == "llm-api" then "5f7ead5503082a71d41a36fd1727325c784e4b79"
|
else if name == "llm-api" then "5f7ead5503082a71d41a36fd1727325c784e4b79"
|
||||||
|
|||||||
+37
-18
@@ -40,6 +40,14 @@ asepharyana.my.id, www.asepharyana.my.id, asepharyana.web.id, www.asepharyana.we
|
|||||||
}
|
}
|
||||||
|
|
||||||
dashboard.asepharyana.my.id {
|
dashboard.asepharyana.my.id {
|
||||||
|
import proxy 4013
|
||||||
|
}
|
||||||
|
|
||||||
|
imphnen.asepharyana.my.id {
|
||||||
|
import proxy 4009
|
||||||
|
}
|
||||||
|
|
||||||
|
scraper.asepharyana.my.id, api.asepharyana.my.id, scraper.asepharyana.web.id, api.asepharyana.web.id {
|
||||||
import proxy 4091
|
import proxy 4091
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +61,23 @@ tools.asepharyana.my.id, tools.asepharyana.web.id {
|
|||||||
|
|
||||||
9router.asepharyana.my.id {
|
9router.asepharyana.my.id {
|
||||||
# LLM streaming: 9router combo models punya TTFT sampe 30-40s (deepseek,
|
# LLM streaming: 9router combo models punya TTFT sampe 30-40s (deepseek,
|
||||||
}
|
# fallback chain). Default (proxy) response_header_timeout 30s / read 60s
|
||||||
|
# bikin false-positive 504 walau 9router masih ngolah. Longgarkan khusus
|
||||||
|
# biar health-check & request PR-Agent real gak kena timeout transient.
|
||||||
|
encode zstd gzip
|
||||||
|
header {
|
||||||
|
-Server
|
||||||
|
X-Content-Type-Options "nosniff"
|
||||||
|
}
|
||||||
|
reverse_proxy 127.0.0.1:4014 {
|
||||||
|
transport http {
|
||||||
|
dial_timeout 3s
|
||||||
|
response_header_timeout 120s
|
||||||
|
read_timeout 300s
|
||||||
|
write_timeout 300s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pr-agent.asepharyana.my.id {
|
pr-agent.asepharyana.my.id {
|
||||||
import proxy 4002
|
import proxy 4002
|
||||||
@@ -80,26 +104,21 @@ ml-zeavisedu.asepharyana.my.id {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upload.asepharyana.my.id, upload.asepharyana.web.id {
|
upload.asepharyana.my.id, upload.asepharyana.web.id {
|
||||||
import proxy 4013
|
|
||||||
}
|
|
||||||
|
|
||||||
imphnen.asepharyana.my.id {
|
|
||||||
import proxy 4009
|
|
||||||
}
|
|
||||||
|
|
||||||
upload.asepharyana.my.id, upload.asepharyana.web.id {
|
|
||||||
# Upload/download besar: JANGAN kompres, JANGAN limit body, flush instan (no buffering)
|
# Upload/download besar: JANGAN kompres, JANGAN limit body, flush instan (no buffering)
|
||||||
reverse_proxy 127.0.0.1:4000 {
|
header {
|
||||||
transport http {
|
-Server
|
||||||
keepalive 120s
|
X-Content-Type-Options "nosniff"
|
||||||
keepalive_interval 30s
|
}
|
||||||
max_conns_per_host 100
|
|
||||||
dial_timeout 3s
|
|
||||||
}
|
|
||||||
flush_interval -1
|
|
||||||
}
|
|
||||||
request_body {
|
request_body {
|
||||||
max_size 0
|
max_size 0
|
||||||
}
|
}
|
||||||
reverse_proxy 127.0.0.1:4000 {
|
reverse_proxy 127.0.0.1:4000 {
|
||||||
|
transport http {
|
||||||
|
dial_timeout 3s
|
||||||
|
read_timeout 300s
|
||||||
|
write_timeout 300s
|
||||||
|
}
|
||||||
|
flush_interval -1
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,30 @@
|
|||||||
# ============================================================
|
# ============================================================
|
||||||
# firewall.sh — deny-by-default firewall untuk orangevps
|
# firewall.sh — deny-by-default firewall untuk orangevps
|
||||||
# Public: 22 (SSH), 80/443 (Caddy), 4013 (hermes dashboard)
|
# Public: 22 (SSH), 80/443 (Caddy), 4013 (hermes dashboard)
|
||||||
|
# 25565 (Minecraft) — WHITELIST TCPShield proxy only
|
||||||
# Tailscale CGNAT 100.64/10: semua port (imrnes & node lain)
|
# Tailscale CGNAT 100.64/10: semua port (imrnes & node lain)
|
||||||
# Localhost: semua
|
# Localhost: semua
|
||||||
# Sisanya: DROP + log
|
# Sisanya: DROP + log
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
# TCPShield proxy ranges (https://tcpshield.com/v4/ + /v4-cf/)
|
||||||
|
# Update saat TCPShield publish range baru.
|
||||||
|
TCPSHIELD_V4=(
|
||||||
|
198.178.119.0/24
|
||||||
|
104.234.6.0/24
|
||||||
|
)
|
||||||
|
TCPSHIELD_V4_CF=(
|
||||||
|
89.222.122.36/31
|
||||||
|
152.233.22.8/31
|
||||||
|
89.222.108.246/31
|
||||||
|
84.17.55.186/31
|
||||||
|
51.79.45.52/31
|
||||||
|
5.135.84.92/30
|
||||||
|
51.75.35.44/30
|
||||||
|
51.161.27.110/31
|
||||||
|
152.233.30.16/31
|
||||||
|
152.233.30.232/31
|
||||||
|
203.205.31.160/31
|
||||||
|
)
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
### IPv4 ###
|
### IPv4 ###
|
||||||
@@ -33,6 +53,10 @@ iptables -A INPUT -p tcp --dport 80 -j ACCEPT
|
|||||||
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||||
# Public: hermes dashboard (auth-protected)
|
# Public: hermes dashboard (auth-protected)
|
||||||
iptables -A INPUT -p tcp --dport 4013 -j ACCEPT
|
iptables -A INPUT -p tcp --dport 4013 -j ACCEPT
|
||||||
|
# Public: Minecraft (FTB sky) — hanya dari proxy TCPShield
|
||||||
|
for cidr in "${TCPSHIELD_V4[@]}" "${TCPSHIELD_V4_CF[@]}"; do
|
||||||
|
iptables -A INPUT -s "$cidr" -p tcp --dport 25565 -j ACCEPT
|
||||||
|
done
|
||||||
|
|
||||||
# ICMP (ping, PMTU)
|
# ICMP (ping, PMTU)
|
||||||
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/sec --limit-burst 10 -j ACCEPT
|
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/sec --limit-burst 10 -j ACCEPT
|
||||||
@@ -66,15 +90,10 @@ ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
|
|||||||
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
|
ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
|
||||||
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
|
ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
|
||||||
ip6tables -A INPUT -p tcp --dport 4013 -j ACCEPT
|
ip6tables -A INPUT -p tcp --dport 4013 -j ACCEPT
|
||||||
# ICMPv6/MLD: ping + neighbor discovery (NIC multicast ff02::1 = MLDv2 reports
|
# Minecraft 25565: TCPShield IPv4 only — tidak ada range IPv6 publik
|
||||||
# dari host lain; kena LOG+DROP tiap menit — 1800 baris/6h di journal).
|
|
||||||
# IPv6 layer-2 discovery WAJIB di-ACCEPT, bukan cuma dropped.
|
|
||||||
ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
ip6tables -A INPUT -p icmpv6 -j ACCEPT
|
||||||
ip6tables -A INPUT -d ff02::1 -j ACCEPT
|
|
||||||
ip6tables -A INPUT -d ff02::2 -j ACCEPT
|
|
||||||
ip6tables -A INPUT -d ff02::fb -j ACCEPT
|
|
||||||
ip6tables -A INPUT -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "FW6-DROP " --log-level 4
|
ip6tables -A INPUT -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "FW6-DROP " --log-level 4
|
||||||
ip6tables -A INPUT -j DROP
|
ip6tables -A INPUT -j DROP
|
||||||
|
|
||||||
echo "Firewall applied:"
|
echo "Firewall applied:"
|
||||||
iptables -L INPUT -n --line-numbers | head -20
|
iptables -L INPUT -n --line-numbers | head -24
|
||||||
|
|||||||
+1
-1
Submodule plugins/hub-guide updated: abd60c607d...ffcd3ba8e3
Reference in New Issue
Block a user