Initial commit
Some checks failed
CI / check (push) Has been cancelled
CI / ida (push) Has been cancelled
CI / cpt (push) Has been cancelled
CI / build-nixos (ena) (push) Has been cancelled
CI / build-nixos (hako) (push) Has been cancelled
CI / build-nixos (kazusa) (push) Has been cancelled
CI / build-nixos (mizuki) (push) Has been cancelled

This commit is contained in:
암냥 2026-07-03 16:53:49 +09:00
commit 70284509f3
No known key found for this signature in database
144 changed files with 7061 additions and 0 deletions

View file

@ -0,0 +1,6 @@
creation_rules:
- path_regex: secrets/.*\.ya?ml$
age:
- age1mgels4hjl7l07gcnt72g86kvhrvd82fha9kuvlp46mpks7unrpmqvy959u # mizuki
- age1dcvh6q9953es9fvt8rq8rdgcktlt64asn2tf2y3vmyz0gntxzynqg2xgzk # hako
- age1p0hw9lwk33x5w83a4gkjva325leq5h0pgeglhcwm4c9kju4qtu4ss7qppr # natsu

View file

@ -0,0 +1,83 @@
{ pkgs, inputs, ... }:
{
imports = [
./hardware-configuration.nix
"${inputs.self}/modules/nixos/base"
"${inputs.self}/modules/nixos/features/boot.nix"
"${inputs.self}/modules/nixos/features/ssh.nix"
"${inputs.self}/modules/nixos/features/docker.nix"
];
# 1. Docker 추가 설정 (IPv6)
virtualisation.docker.daemon.settings = {
fixed-cidr-v6 = "fd00::/80";
ipv6 = true;
};
# 2. 크론 설정
services.cron = {
enable = true;
systemCronJobs = [
"1 0 * * * imnyang * * * * * printf '\n%s : ' '$(date)' >> /home/imnyang/codelounge.log && /home/imnyang/codelounge.sh >> /home/imnyang/codelounge.log"
];
};
services.netbird.enable = true;
# 3. 사용자 SSH 키 등록
users.users.imnyang.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOHP3Z+AYrRh9f8TYyqChKfeyNm3lOe0F75AwRHTTaxD imnyang@kazusa"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIrpjEYOBx7LTGb7QsPrmPBboqyTUNm/e+4+yqWruljv imnyang@natsu"
];
environment.systemPackages = with pkgs; [
eza
neovim
nil
nixd
bun
stdenv.cc.cc.lib
];
programs.nix-ld.enable = true;
systemd.services.blog = {
description = "blog.imnya.ng";
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "simple";
User = "imnyang";
Environment = [
"LD_LIBRARY_PATH=${pkgs.stdenv.cc.cc.lib}/lib"
];
WorkingDirectory = "/home/imnyang/git/imnyang/blog";
ExecStart = "${pkgs.bun}/bin/bun run preview";
Restart = "always";
RestartSec = 5;
};
path = [ pkgs.bun ];
};
services.qemuGuest.enable = true;
boot.kernel.sysctl = {
"net.ipv4.ip_forward" = 1;
"net.ipv6.conf.all.forwarding" = 1;
};
programs.git.config = {
safe.directory = "*";
};
networking.firewall.allowedTCPPorts = [
22
80
443
];
networking.hostName = "natsu";
system.stateVersion = "26.05";
}

View file

@ -0,0 +1,30 @@
{
inputs,
overlays,
}:
let
inherit (inputs) nixpkgs home-manager sops-nix;
in
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
sops-nix.nixosModules.sops
# ./services/attic.nix
./services/caddy.nix
./services/forgejo-runner.nix
# ./services/harmonia.nix
./configuration.nix
./hardware-configuration.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = { inherit inputs; };
home-manager.users.imnyang = import ./home.nix;
}
];
specialArgs = {
inherit inputs;
inherit overlays;
};
}

View file

@ -0,0 +1,31 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/ffe787e4-f39c-4c9b-b2f5-273386198307";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-uuid/E854-0DD3";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
swapDevices = [ ];
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";
}

View file

@ -0,0 +1,80 @@
{
config,
pkgs,
inputs,
...
}:
let
nr = import "${inputs.self}/modules/nixos/features/packages/nr.nix" { inherit pkgs; };
nrr = import "${inputs.self}/modules/nixos/features/packages/nrr.nix" { inherit pkgs; };
in
{
home.stateVersion = "26.05";
home.username = "imnyang";
home.homeDirectory = "/home/imnyang";
home.packages = [
nr
nrr
];
home.sessionVariables = {
EDITOR = "nano";
VISUAL = "nano";
};
programs.fish = {
enable = true;
shellAliases = {
# 디렉토리 네비게이션
".." = "cd ..";
"..." = "cd ../..";
# ls 별칭
ls = "eza";
ll = "eza -l";
la = "eza -a";
lla = "eza -la";
# NixOS 관련
rebuild = "sudo nixos-rebuild switch --flake .#natsu";
update = "nix flake update";
clean = "sudo nix-collect-garbage -d";
};
interactiveShellInit = ''
set -g fish_greeting ""
set -g fish_color_command blue
set -g fish_color_error red
set -g fish_color_param cyan
'';
};
programs.starship = {
enable = true;
settings = {
format = "$username@$hostname:$directory$character";
add_newline = false;
username = {
style_user = "purple";
style_root = "purple";
format = "[$user]($style)";
show_always = true;
};
hostname = {
style = "green";
format = "[$hostname]($style)";
ssh_only = false;
};
directory = {
style = "blue";
format = "[$path]($style)";
truncation_length = 3;
};
character = {
success_symbol = " >";
error_symbol = " >";
};
};
};
}

View file

@ -0,0 +1,35 @@
forgejo-runner:
token: ENC[AES256_GCM,data:NBOcn5Z99hyQEHotUuVOwvlOqd/lKrXy4pUSobbmPSnVB5yAzTdUv5vv+J9z27z4wg==,iv:C9QBd+Kw2BcX+LkTwuRHpl/G6fw8iGWJPIWDvL8lcKU=,tag:2ZRQzx2P6THlpuDDdpuZgw==,type:str]
sops:
age:
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLNzVoeHM2LzRYdGp5Snlj
UUlKNThlczFZcFJKMXpJSG42eHVLbjFsamxNCkZiaGNJRFA4bmZHT0g4ZytjZEJY
SHhWblNOa2ZGUWtJZzZLYi9RTjJjcW8KLS0tIHRBV0Z6bEdybUppSHpGMHBsN1A2
ZitWOTJsUHlvUXp3NEtUK0Jwc1VSU1EK9tZNPBKuY9G0vsDP0RMA/W2xBrN5LBj1
0j9N309gyFNqCuR3ZEpoarAx6rpD1Q8wQYhhZQw+z7h2+eGPNp9Qvw==
-----END AGE ENCRYPTED FILE-----
recipient: age10kkqzxkxdkr9322fd536gcs43xqvdw609ffpc4vqqf3f77tzmvlq45q55s
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1VDI1L0lzZHVTMHNaRTZS
Y3prZnpNMFEwL2dPdlZreGRjRzNLUGFFZEVNCndML3BHKy9EaGpqREVlQVJCdkRC
MXlMeW5sTXZzUE83d2FtbW5ybHh5dzAKLS0tIDVKdTNxdC9yRCtvQmhNbzhtdFA4
OFJtaG0rcHFPaHJUVjNKckl5UGpDSm8K1cyMiVEVir4uaFJuwQkpcbLmXet4txX+
9QrM+WQr73JfoIirHZhZLM0aAXQDwXG791N6iu2x/Q9BbbqLT5c73A==
-----END AGE ENCRYPTED FILE-----
recipient: age1dcvh6q9953es9fvt8rq8rdgcktlt64asn2tf2y3vmyz0gntxzynqg2xgzk
- enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArTzJNUkZWVCtQNVpyeEpj
TG44TEppaXkrR2M4K3Y2TEVFWHlKWDYwaFY0CmxNN3Awb0wzUHo0Q21yUERBUXBz
WXYzL0VHcnQxa3UwS3hMRzM0cndtUjAKLS0tIERjaDhZYzlJWmZ6R09Ub0NmTytT
QjZxRUJGU01XRCs5aGZVUElTQ2wxTUEKhnM25DGalV+mfPp8FD40x25Eq5/XudPn
jBWu84zEtL8Ja9XECKaXJiP7oi1YaX8+BV8BdlIfDGR9ceiZRIhlrA==
-----END AGE ENCRYPTED FILE-----
recipient: age1p0hw9lwk33x5w83a4gkjva325leq5h0pgeglhcwm4c9kju4qtu4ss7qppr
lastmodified: "2026-05-28T02:55:30Z"
mac: ENC[AES256_GCM,data:DSY6wQyYBBWcA9aqZkFVJ7JyvFTvXm3r6Zu4xE0dStBgyv/0O5l0pEmekKlYuMWXd3VmAWhH7VCsVN7RyeoLpimm97MfedKIfd/wVISuBy0SA2q3frfwbuith6yfXRqmsGNzG7ivnZ146w8uWGf5RCef1m2Nl9QPeai7dUcB/3c=,iv:XPV8gTSWJzXoOj5bqa+R23deWD2GUaQp+w2b9ThG6V4=,tag:BLWeaRbfYjV8fzieemVBfg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.13.1

View file

@ -0,0 +1,122 @@
{ pkgs, ... }:
{
services.caddy = {
enable = true;
virtualHosts."http://natsu.icn.mizuki.guru".extraConfig = ''
respond "" 200
'';
virtualHosts."https://file.mizuki.guru".extraConfig = ''
reverse_proxy 10.11.8.112 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
}
'';
virtualHosts."http://file.mizuki.guru".extraConfig = ''
reverse_proxy 10.11.8.112 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
}
'';
virtualHosts."auth.mizuki.guru".extraConfig = ''
reverse_proxy 10.11.8.102:9080
'';
virtualHosts."plutos.dazzle.st".extraConfig = ''
reverse_proxy epc.hikari.mizuki.arpa:3000
'';
virtualHosts."event.dazzle.st".extraConfig = ''
reverse_proxy 10.11.8.102:9794
'';
virtualHosts."pve.hikari.icn.mizuki.guru".extraConfig = ''
reverse_proxy https://10.11.8.100:8006 {
header_up X-Real-Ip {remote_host}
header_up X-Http-Version {http.request.proto}
transport http {
tls_insecure_skip_verify
}
}
'';
virtualHosts."cockpit.hikari.icn.mizuki.guru".extraConfig = ''
reverse_proxy https://10.11.8.100:9090 {
header_up X-Real-Ip {remote_host}
header_up X-Http-Version {http.request.proto}
transport http {
tls_insecure_skip_verify
}
}
'';
virtualHosts."cache.mizuki.guru".extraConfig = ''
reverse_proxy 127.0.0.1:5000
'';
virtualHosts."paste.mizuki.guru".extraConfig = ''
reverse_proxy 10.11.8.102:11108
'';
virtualHosts."komodo.mizuki.guru".extraConfig = ''
reverse_proxy 10.11.8.102:9120
'';
virtualHosts."ena.mizuki.guru".extraConfig = ''
basic_auth {
imnyang $2a$10$zA83XKt84pcXiwfkuvNmKOpQ5Cw0IP6m/.1AX0ahkVQaPOzrmFlxm
}
reverse_proxy 10.20.31.103:3000
'';
virtualHosts."akiyama.mizuki.guru".extraConfig = ''
rewrite / /index.avif
root * /var/static/akiyama.mizuki.guru
file_server
'';
virtualHosts."chef.mizuki.guru".extraConfig = ''
root * /var/static/chef.mizuki.guru
rewrite / /CyberChef_v10.22.1.html
file_server {
precompressed br gzip
}
header {
Cache-Control "public, max-age=31536000"
}
'';
virtualHosts."blog.imnya.ng".extraConfig = ''
reverse_proxy 127.0.0.1:4321
'';
virtualHosts."netbird.mizuki.guru".extraConfig = ''
# Native gRPC (needs HTTP/2 cleartext to backend)
@grpc header Content-Type application/grpc*
reverse_proxy @grpc h2c://127.0.0.1:8081
# Combined server paths (relay, signal, management, OAuth2)
@backend path /relay* /ws-proxy/* /api/* /oauth2/*
reverse_proxy @backend 127.0.0.1:8081
# Dashboard (everything else)
reverse_proxy /* 127.0.0.1:8080
'';
package = pkgs.caddy.withPlugins {
plugins = [
"github.com/caddy-dns/cloudflare@v0.2.2"
"github.com/aksdb/caddy-cgi/v2@v2.2.6"
"github.com/shift72/caddy-geo-ip@v0.6.0"
"github.com/lolPants/caddy-requestid@v1.1.2"
"github.com/WeidiDeng/caddy-cloudflare-ip@v0.0.0-20231130002422-f53b62aa13cb"
"github.com/caddyserver/ntlm-transport@v0.1.2"
"github.com/ueffel/caddy-brotli@v1.6.0"
"github.com/RussellLuo/caddy-ext/ratelimit@v0.3.0"
"github.com/neodyme-labs/user_agent_parse@v0.0.1"
];
hash = "sha256-n0LkDBE3JB3zrGYND0EGrKXC+CT0SzRiIjj0QXNZZ8k=";
};
};
}

View file

@ -0,0 +1,67 @@
{
config,
lib,
pkgs,
...
}:
let
runnerSecret = key: {
sopsFile = ../secrets/forgejo-runner.yaml;
inherit key;
owner = "root";
group = "root";
};
in
{
sops.secrets."forgejo-runner/token" = runnerSecret "forgejo-runner/token";
services.gitea-actions-runner = {
package = pkgs.forgejo-runner;
instances.my-forgejo-instance = {
enable = true;
name = "natsu-cicd";
tokenFile = config.sops.secrets."forgejo-runner/token".path;
url = "https://git.mizuki.guru/";
labels = [
"node-24:docker://node:24-bookworm"
"nixos-latest:docker://nixos/nix"
"native:host"
"AArch64:host"
"ubuntu-latest:docker://git.mizuki.guru/packages/act:ubuntu-latest-aarch64"
];
# act 엔진의 컨테이너 보안 가드 및 디렉토리 이탈 방지 설정 주입
settings = {
container = {
# 호스트 측의 임시 디렉토리 마운트 허용 범위를 명시
valid_volumes = [
"/var/run/docker.sock"
"/tmp"
"/run/user"
];
# 컨테이너 내 작업 디렉토리를 절대 경로로 고정하여 탈출 방지
workdir = "/workspace";
};
runner = {
# act 실행 환경 내부 임시 경로 강제 고정
envs = {
ACT_TEMP_DIR = "/tmp/act";
};
};
};
hostPackages = with pkgs; [
bash
git
python3
docker
docker-compose
docker-buildx
nodejs
bun
wget
curl
];
};
};
}