HAL 제어 평면(릴리스·서버·Agent·작업·모듈 배포·운영자 계정·긴급 복구·재해복구·공개 상태), Node Agent, 배포 스크립트·유닛·nginx 템플릿, 릴리스 도구, 포털 HAL 클라이언트 (§28·§29·§32~§34)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
zzabisagent-lab
2026-10-26 11:58:15 +00:00
co-authored by Claude Fable 5.1
parent 403d0fb845
commit 6b5a014041
49 changed files with 2584 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
# hal.ariweb.net — HAL(제어 평면). 운영자 콘솔 /ops 는 HAL 이 네트워크 관문(허용 CIDR 또는 접근권 쿠키)을 적용한다.
# Agent 는 /agent/v1 로, 포털은 /portal/v1 로 서명된 요청을 보낸다. 큰 전송(/agent/v1/transfers)은 본문 제한을 넉넉히 둔다.
server {
listen 80;
listen [::]:80;
server_name {{HAL_HOST}};
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{HAL_HOST}};
server_tokens off;
client_max_body_size 0;
ssl_certificate {{CERT_DIR}}/fullchain.pem;
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://127.0.0.1:{{PORT}};
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_request_buffering off;
proxy_buffering off;
proxy_read_timeout 120s;
}
}
+29
View File
@@ -0,0 +1,29 @@
# my.ariweb.net — 고객 포털
server {
listen 80;
listen [::]:80;
server_name {{PORTAL_HOST}};
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{PORTAL_HOST}};
server_tokens off;
client_max_body_size 200m;
ssl_certificate {{CERT_DIR}}/fullchain.pem;
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
proxy_pass http://127.0.0.1:{{PORT}};
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_read_timeout 300s;
}
}
+3
View File
@@ -0,0 +1,3 @@
# deploy/nginx/awstats.conf — /etc/nginx/conf.d/awstats.conf : Ariweb 관리형 사이트 접속 통계 로그 형식(§13.1).
# Agent(site.usage)가 사이트별 로그(aw-<siteId>.access.log)를 읽어 요청 수·수신/송신 바이트·오류율·응답 시간을 집계한다. IP 는 기록하지 않는다(개인정보 최소화).
log_format awstats '$time_iso8601|$host|$request_length|$bytes_sent|$status|$request_time|$uri';
+7
View File
@@ -0,0 +1,7 @@
server {
listen 80;
listen [::]:80;
server_name {{OLD_NAMES}};
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
return 301 https://{{PRIMARY}}$request_uri;
}
+7
View File
@@ -0,0 +1,7 @@
access_log {{LOG}} awstats;
error_page 503 /__aw_maint;
location = /__aw_maint { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{MAINT_HTML}}'; }
if (-f {{SITE_DIR}}/.maintenance) { return 503; }
if (-f {{SITE_DIR}}/.limited) { rewrite ^ /__aw_limited last; }
location = /__aw_limited { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{LIMIT_HTML}}'; }
location / { proxy_pass http://127.0.0.1:{{PORT}}; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 300s; }
+11
View File
@@ -0,0 +1,11 @@
root {{ROOT}};
index index.html;
access_log {{LOG}} awstats;
error_page 503 /__aw_maint;
location = /__aw_maint { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{MAINT_HTML}}'; }
if (-f {{SITE_DIR}}/.maintenance) { return 503; }
if (-f {{SITE_DIR}}/.limited) { rewrite ^ /__aw_limited last; }
location = /__aw_limited { internal; default_type text/html; add_header Cache-Control "no-store" always; return 503 '{{LIMIT_HTML}}'; }
location ~ /\. { return 404; }
location / { try_files $uri $uri/ /index.html =404; add_header Cache-Control "no-cache" always; }
location /uploads/ { alias {{SITE_DIR}}/data/uploads/; }
+12
View File
@@ -0,0 +1,12 @@
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name {{SERVER_NAMES}};
server_tokens off;
client_max_body_size 64m;
ssl_certificate {{CERT_DIR}}/fullchain.pem;
ssl_certificate_key {{CERT_DIR}}/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options "nosniff" always;
{{BODY}}
}
+11
View File
@@ -0,0 +1,11 @@
# Ariweb 관리형 사이트 vhost — Agent 가 만든다(site.deploy/domain.vhost). 손으로 고치지 마세요(다음 배포 때 덮어씁니다).
# 사이트 {{SITE_ID}} · 도메인 {{DOMAIN_LIST}} · 생성 {{GENERATED_AT}}
server {
listen 80;
listen [::]:80;
server_name {{SERVER_NAMES}};
server_tokens off;
location ^~ /.well-known/acme-challenge/ { root {{ACME_ROOT}}; default_type text/plain; }
{{HTTP_BODY}}
}
{{HTTPS_SERVER}}