Compare commits

...

6 Commits

Author SHA1 Message Date
1e4024ac02 account.org.gpg: 添加 Vultr 2FA 恢复码 2026-08-29 06:02:47 +08:00
43603b8f50 docker: 重新组织服务配置
- 用功能更强大的 WebDAV 代替掉 OWSS
- WebDAV 和 v2raya 服务都拆成单独的配置文件
2026-08-29 06:01:18 +08:00
0f79d5ca9b ansible: 添加 xray 服务部署配置 2026-08-23 01:05:08 +08:00
3329694df2 ansible: 添加 frp 服务端部署配置 2026-08-22 21:51:51 +08:00
6f5e3dee55 ansible: 服务器初始化时显式开启 ssh 公钥认证 2026-08-22 16:10:09 +08:00
eef4881ffd ansible: 新增 VPS 初始化 playbook 与 shadowsocks-libev 部署配置 2026-08-22 16:10:00 +08:00
15 changed files with 412 additions and 18 deletions

View File

@@ -0,0 +1,4 @@
---
ansible_user: zedhugh
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_port: 44444

2
ansible/inventory.ini Normal file
View File

@@ -0,0 +1,2 @@
[vps_debian]
yunyoo-tokyo

View File

@@ -0,0 +1,85 @@
---
- name: 配置 frps 服务端
hosts: vps_debian
gather_facts: false
become: true
vars:
frp_version: "0.71.0"
frp_download_url: "https://github.com/fatedier/frp/releases/download/v{{ frp_version }}/frp_{{ frp_version }}_linux_amd64.tar.gz"
frp_local_archive: "/tmp/frp_{{ frp_version }}_linux_amd64.tar.gz"
frp_local_tmp_dir: "/tmp/frp_{{ frp_version }}_linux_amd64"
frp_install_dir: "/opt/frp"
frp_config_dir: "/etc/frp"
vars_files:
- ../vars/vault.yaml
tasks:
- name: 创建 frp 目录
file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- "{{ frp_install_dir }}"
- "{{ frp_config_dir }}"
- name: 检查本地是否已有该版本的压缩包
stat:
path: "{{ frp_local_archive }}"
register: local_archive
delegate_to: localhost
run_once: true
- name: 下载 frp 压缩包到本地
get_url:
url: "{{ frp_download_url }}"
dest: "{{ frp_local_archive }}"
timeout: 60
delegate_to: localhost
run_once: true
become: false
when: not local_archive.stat.exists
- name: 解压 frp 压缩包到本地
unarchive:
src: "{{ frp_local_archive }}"
dest: "/tmp/"
creates: "{{ frp_local_tmp_dir }}"
delegate_to: localhost
run_once: true
become: false
when: not local_archive.stat.exists
- name: 复制 frps 二进制文件到目标机器
copy:
src: "{{ frp_local_tmp_dir }}/frps"
dest: "{{ frp_install_dir }}/frps"
mode: '0755'
notify: restart frps
- name: 生成 frps.toml 配置文件
template:
src: ../templates/frps.toml.j2
dest: "{{ frp_config_dir }}/frps.toml"
mode: '0644'
notify: restart frps
- name: 创建 frps 的 systemd 服务文件
template:
src: ../templates/frps.service.j2
dest: /etc/systemd/system/frps.service
mode: '0644'
notify: restart frps
- name: 启用并启动 frps 服务
systemd:
name: frps
enabled: true
state: started
daemon_reload: true
handlers:
- name: restart frps
systemd:
name: frps
state: restarted

View File

@@ -0,0 +1,34 @@
---
- name: 配置 shadowsocks-libev 服务器
hosts: vps_debian
become: true
vars_files:
- ../vars/vault.yaml
tasks:
- name: 安装 shadowsocks-libev
apt:
name: shadowsocks-libev
state: present
update_cache: true
- name: 配置 shadowsocks-libev 服务器
template:
src: ../templates/ss-config.json.j2
dest: /etc/shadowsocks-libev/config.json
owner: root
group: root
mode: '0644'
notify: restart shadowsocks-libev server
- name: 启动 shadowsocks-libev 服务器
systemd:
name: shadowsocks-libev
enabled: true
state: started
handlers:
- name: restart shadowsocks-libev server
systemd:
name: shadowsocks-libev
state: restarted

View File

@@ -0,0 +1,95 @@
---
- name: 新机器初始化
hosts: vps_debian
gather_facts: yes
vars:
ansible_user: root
ansible_ssh_port: 22
admin_user: zedhugh
ssh_port: 44444
timezone: Asia/Shanghai
ssh_public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
tasks:
- name: 启用 BBR
sysctl:
name: net.ipv4.tcp_congestion_control
value: bbr
sysctl_set: yes
reload: yes
- name: 设置时区
timezone:
name: "{{ timezone }}"
- name: 创建管理员用户
user:
name: "{{ admin_user }}"
shell: /bin/bash
create_home: yes
state: present
- name: 确保 sudo 已安装
apt:
name: sudo
state: present
- name: 确保 sudoers.d 目录存在
file:
path: /etc/sudoers.d
state: directory
owner: root
group: root
mode: '0755'
- name: 配置 sudo 免密码
copy:
content: "{{ admin_user }} ALL=(ALL) NOPASSWD: ALL\n"
dest: "/etc/sudoers.d/{{ admin_user }}"
owner: root
group: root
mode: '0440'
validate: '/usr/sbin/visudo -cf %s'
- name: 复制 SSH 密钥
authorized_key:
user: "{{ admin_user }}"
key: "{{ ssh_public_key }}"
state: present
- name: 修改 SSH 端口
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?Port "
line: "Port {{ ssh_port }}"
notify: restart ssh
- name: 禁止 root 密码登录
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?PermitRootLogin"
line: "PermitRootLogin prohibit-password"
notify: restart ssh
- name: 禁止密码认证
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?PasswordAuthentication"
line: "PasswordAuthentication no"
notify: restart ssh
- name: 开启公钥认证
lineinfile:
path: /etc/ssh/sshd_config
regexp: "^#?PubkeyAuthentication"
line: "PubkeyAuthentication yes"
notify: restart ssh
handlers:
- name: restart ssh
systemd:
name: sshd
state: restarted

View File

@@ -0,0 +1,45 @@
---
- name: 配置 xray 服务
hosts: vps_debian
become: true
gather_facts: false
vars:
xray_config_file: /usr/local/etc/xray/config.json
xray_bin: /usr/local/bin/xray
vars_files:
- ../vars/vault.yaml
tasks:
- name: 确保有 curl 软件包
apt:
name:
- curl
state: present
update_cache: true
- name: 安装 xray
shell: |
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
notify: restart xray
- name: 生成 xray 配置
template:
src: ../templates/xray-config.json.j2
dest: "{{ xray_config_file }}"
owner: root
group: root
mode: '0644'
notify: restart xray
- name: 启动 xray 服务并添加开机启动
systemd:
name: xray
enabled: true
state: started
daemon_reload: true
handlers:
- name: restart xray
systemd:
name: xray
state: restarted

View File

@@ -0,0 +1,13 @@
[Uint]
Description=Frp Server Service
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=5s
ExecStart={{ frp_install_dir }}/frps -c {{ frp_config_dir }}/frps.toml
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,14 @@
bindPort = {{ vault_frps_bind_port }}
vhostHTTPPort = {{ vault_frps_vhost_http_port }}
vhostHTTPSPort = {{ vault_frps_vhost_https_port }}
auth.method = "token"
auth.token = "{{ vault_frps_token }}"
webServer.addr = "0.0.0.0"
webServer.port = {{ vault_frps_dashboard_port }}
webServer.user = "{{ vault_frps_dashboard_user }}"
webServer.password = "{{ vault_frps_dashboard_password }}"
log.to = "/var/log/frps.log"

View File

@@ -0,0 +1,9 @@
{
"server": "0.0.0.0",
"mode": "{{ vault_ss_mode }}",
"server_port": {{ vault_ss_server_port }},
"local_port": {{ vault_ss_local_port }},
"password": "{{ vault_ss_password }}",
"timeout": 60,
"method": "{{ vault_ss_method }}"
}

View File

@@ -7,12 +7,12 @@
"inbounds": [
{
"listen": "0.0.0.0",
"port": 443,
"port": {{ vault_xray_port }},
"protocol": "vless",
"settings": {
"clients": [
{
"id": "817a867d-7bcf-48d1-b30e-5c6794852e13",
"id": "{{ vault_xray_uuid }}",
"flow": "xtls-rprx-vision"
}
],
@@ -24,9 +24,9 @@
"security": "reality",
"realitySettings": {
"dest": "dl.google.com:443",
"serverNames": ["www.cloudflare.com"],
"privateKey": "uJQs7FOMjafiU-7kxOUpfJut8ocj5kpr_p-zH7RTt1g",
"shortIds": ["1e21014957dfc7a9"]
"serverNames": ["dl.google.com"],
"privateKey": "{{ vault_xray_private_key }}",
"shortIds": ["{{ vault_xray_short_id }}"]
}
},
"sniffing": {

34
ansible/vars/vault.yaml Normal file
View File

@@ -0,0 +1,34 @@
$ANSIBLE_VAULT;1.1;AES256
31623833356637343262363863626534323535626238346439333262633332633136633261306466
6236333066363461326664306262633937323864306462370a333631643039653664643662366234
30643231336631313930663637396537663162623938363263336333343262376561323765356630
6332383136383336640a336536316566393461666463616265363830383331363838613839636338
63666365333233646533303166316333393535313466393832643966306331666434333065333238
37633735313832366131653833363762393265656439663135376265366466333838623761646535
64633236663738653233633566633734306138393462383532306436373537343332343565356466
62386664373631336138396134613833636232663936363963656638353133386430376631383438
35313866343438636564373566373239656233376432363362613466356334346339616562316530
62306361646362353631336134326136346663623061643231666433353265653736323162616166
32313132643832306563623861393735623439376432346136623732353737356338616432316161
64316436653531356362316366383039616465313233393663663566316532626138363936363736
31386237653634343236326639376531653465636233636662303037643930633661623338356537
34636639383662646234313037363230373333333731323666383232626330663561396330356361
36346537376431333235393938636664306532373863353862663166613862363165643433626361
37616337356538373733313130633334353436643437366534326636616539316166336137346461
63633130623436316463623461353762313533636262653262393930666434386664326464636562
35636233656365616332383565623230353062663236316437333830626463333366633230393432
33386533346436623132313036646536366339646333643732633133626631396463653533363763
37623439303931363933336432386430336662353138663231316436356535373831653232633562
33626463303134323032643535373038303530376632393162356630613134396261633661393335
30646133366166313533666565326335656231663864666333366136616264356535303033313832
35323432613063356161383365653964613339346136333363363763316463396364383264343634
65623039343064356430386662323135303134306539313138316633396635333331636137356665
38623531613138316162353733663631396562313033393066303266396533613762643936663936
65663762646264616439666138636364343264323961343739336330663237666661303639363835
63636562636336613665366533333563323239633338663738363931383333356264313166393132
30643636303333616161346166323933623432613633643965313366643565343931633338303237
35636365333262386135623866343839313836616664663764323938636630393062383462343437
32636664663635643934396166373462303638343437623961373362366230633466363936326162
38303130346439323863643836666565326530363362306432623036303562636532333966386463
31353063363839633736366133353535643064363461653030346432393461623666616666643231
63333831653963356632316333396130653934653134623339323438653638643031

View File

@@ -1,17 +1,4 @@
services:
owss:
image: ronggang/owss:latest
container_name: owss
restart: always
privileged: true
# host 模式和 bridge 模式二选一
network_mode: host
# ports:
# - "8088:8088"
volumes:
- /OWSS/storage:/app/storage
- /OWSS/config:/app/config
v2raya:
image: mzz2017/v2raya:latest
container_name: v2raya

36
docker/webdav-config.yaml Normal file
View File

@@ -0,0 +1,36 @@
address: 0.0.0.0
port: 46065
auth: true
prefix: /
tls: false
behindProxy: true
log:
format: console
colors: true
outputs:
- /logs/webdav.log
logLevel: info
directory: /data
permissions: R
users:
- username: zedhugh
password: "{bcrypt}$2a$10$nP6GQJidzLyhwkkQGQH/KOAQq2KjNW5Fbb.I/XD2OD2oxCxEoXbUO"
directory: /data
permissions: CRUD
- username: PT
password: "{bcrypt}$2a$10$cK9NWvSafxne2Fv6P6ZH7.Q/tVKk5M4pqXgsuOi2bF/zsCopFHsC2"
directory: /data/users/PT
permissions: CRUD
- username: v2rayNG
password: "{bcrypt}$2a$10$jvjejyOea8Xqsik8a9M71.rvC/0kdFah2WuMCTKHBQJ8PxGkdFmKC"
directory: /data/users/v2rayNG
permissions: CRUD
- username: guest
password: "guest"
directory: /data/public
permissions: R

36
docker/webdav.yaml Normal file
View File

@@ -0,0 +1,36 @@
x-data-volume: &data-volume
type: bind
source: /var/db/webDAV
target: /data
x-user-dirs: &user-dirs
/data/users/PT
/data/users/v2rayNG
/data/public
services:
WebDAV-init:
image: busybox:latest
container_name: webdav-init
restart: no
volumes:
- *data-volume
environment:
DIRS: *user-dirs
command: sh -c "mkdir -p $$DIRS"
WebDAV:
image: hacdias/webdav:latest
container_name: webdav
restart: always
depends_on:
WebDAV-init:
condition: service_completed_successfully
command: ["-c", "/config.yaml"]
network_mode: host
volumes:
- ./webdav-config.yaml:/config.yaml:ro
- /var/log:/logs
- *data-volume
environment:
TZ: Asia/Shanghai

Binary file not shown.