浏览代码

feat: init

kotoyuuko 6 月之前
父节点
当前提交
bc08f7d4bc

+ 86 - 0
01_server_init.sh

@@ -0,0 +1,86 @@
+#!/bin/bash
+
+SSH_PORT="$1"
+SWAP_SIZE="$2"
+
+# install basic packages
+apt update
+apt install -y \
+    ca-certificates \
+    apt-transport-https \
+    git \
+    curl \
+    wget \
+    unzip \
+    screen \
+    net-tools \
+    dnsutils \
+    nano \
+    gnupg2 \
+    resolvconf
+
+# use DEB822 format
+rm -f /etc/apt/sources.list
+cat > /etc/apt/sources.list.d/debian.sources << EOF
+Types: deb
+URIs: https://deb.debian.org/debian
+Suites: trixie trixie-updates trixie-backports
+Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
+
+Types: deb
+URIs: https://security.debian.org/debian-security
+Suites: trixie-security
+Components: main contrib non-free non-free-firmware
+Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
+EOF
+apt update
+apt upgrade -y
+
+# setup swap
+fallocate -l $SWAP_SIZE /swapfile
+chmod 600 /swapfile
+mkswap /swapfile
+swapon /swapfile
+cat <<EOF >> /etc/fstab
+/swapfile none swap sw 0 0
+EOF
+mount -a
+
+# setup ntp
+apt update
+apt install chrony
+systemctl enable chrony
+systemctl restart chrony
+
+# setup ssh
+sed -i 's/^#\?PermitRootLogin.*$/PermitRootLogin no/g' /etc/ssh/sshd_config
+sed -i 's/^#\?PubkeyAuthentication.*$/PubkeyAuthentication yes/g' /etc/ssh/sshd_config
+sed -i 's/^#\?PasswordAuthentication.*$/PasswordAuthentication no/g' /etc/ssh/sshd_config
+systemctl restart sshd
+
+# setup fail2ban
+apt update
+apt install fail2ban
+cat > /etc/fail2ban/jail.local << EOF
+[DEFAULT]
+ignoreip = 127.0.0.1/8 ::1
+bantime  = 1h
+findtime = 10m
+maxretry = 3
+
+[sshd]
+enabled = true
+port    = $SSH_PORT
+logpath = /var/log/auth.log 
+EOF
+systemctl enable fail2ban
+systemctl restart fail2ban
+
+# setup ufw
+apt install ufw
+ufw default deny incoming
+ufw default allow outgoing
+sed -i 's/IPV6=no/IPV6=yes/' /etc/default/ufw
+ufw allow $SSH_PORT/tcp
+ufw enable

+ 55 - 0
02_install_nginx.sh

@@ -0,0 +1,55 @@
+#!/bin/bash
+
+CERT_DOMAIN="$1"
+
+# install the prerequisites
+apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
+
+# import gpg key
+curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
+    | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
+    
+# verify gpg key
+mkdir -m 700 ~/.gnupg
+gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg
+
+echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
+http://nginx.org/packages/debian `lsb_release -cs` nginx" \
+    | tee /etc/apt/sources.list.d/nginx.list
+
+# install nginx
+apt update
+apt install -y nginx
+
+# start nginx
+systemctl start nginx
+systemctl enable nginx
+
+# generate self signed cert
+mkdir -p /etc/nginx/certs/self
+openssl genrsa -out /etc/nginx/certs/self/privkey.pem 2048
+openssl req -new -x509 -days 3650 -key /etc/nginx/certs/self/privkey.pem \
+    -out /etc/nginx/certs/self/cert.pem \
+    -subj "/C=CN/O=Self Hosted/OU=SRE/CN=$DOMAIN/CN=*.$DOMAIN"
+
+# default vhost
+rm -f /etc/nginx/conf.d/default.conf
+cat > /etc/nginx/conf.d/00-default.conf << EOF
+server {
+    listen 80 default_server;
+    listen [::]:80 default_server;
+    server_name _;
+    return 418;
+}
+
+server {
+    listen 443 ssl default_server;
+    listen [::]:443 ssl default_server;
+    server_name _;
+    ssl_certificate /etc/nginx/certs/self/cert.pem;
+    ssl_certificate_key /etc/nginx/certs/self/privkey.pem;
+    return 418;
+}
+EOF
+nginx -t
+systemctl force-reload nginx

+ 4 - 0
03_install_docker.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+# install docker
+curl -fsSL https://raw.githubusercontent.com/docker/docker-install/master/install.sh | sh

+ 24 - 0
04_allow_cloudflare.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# download scripts
+curl -fLO https://raw.githubusercontent.com/kotoyuuko/debian-server-init/refs/heads/main/scripts/update_cloudflare_ips_for_ufw.sh
+curl -fLO https://raw.githubusercontent.com/kotoyuuko/debian-server-init/refs/heads/main/scripts/update_cloudflare_ips_for_nginx.sh
+
+# move scripts
+mkdir -p /scripts/cloudflare
+mv update_cloudflare_ips_for_ufw.sh /scripts/cloudflare/
+mv update_cloudflare_ips_for_nginx.sh /scripts/cloudflare/
+chmod +x /scripts/cloudflare/update_cloudflare_ips_for_ufw.sh
+chmod +x /scripts/cloudflare/update_cloudflare_ips_for_nginx.sh
+
+# run scripts
+bash /scripts/cloudflare/update_cloudflare_ips_for_ufw.sh
+bash /scripts/cloudflare/update_cloudflare_ips_for_nginx.sh
+
+# tasks
+UFW_JOB="0 3 * * * /scripts/cloudflare/update_cloudflare_ips_for_ufw.sh > /dev/null 2>&1"
+NGINX_JOB="10 3 * * * /scripts/cloudflare/update_cloudflare_ips_for_nginx.sh /etc/nginx/cloudflare/real_ip.conf > /dev/null 2>&1"
+
+# add crontab
+(crontab -l 2>/dev/null | grep -Fq "$UFW_JOB") || (crontab -l 2>/dev/null; echo "$UFW_JOB") | crontab -
+(crontab -l 2>/dev/null | grep -Fq "$NGINX_JOB") || (crontab -l 2>/dev/null; echo "$NGINX_JOB") | crontab -

+ 30 - 0
README.md

@@ -1,3 +1,33 @@
 # Debian Server Init
 
 ---
+
+## Reinstall Debian
+
+```shell
+curl -fLO https://raw.githubusercontent.com/bohanyang/debi/master/debi.sh
+chmod +x debi.sh
+./debi.sh \
+    --version 13 \
+    --architecture amd64 \
+    --cloudflare \
+    --user username \
+    --authorized-keys-url https://github.com/username.keys \
+    --ssh-port 22 \
+    --bbr
+reboot
+```
+
+## Init New Server
+
+```shell
+apt update
+apt install -y git
+git clone https://github.com/kotoyuuko/debian-server-init
+cd debian-server-init
+chmod +x *.sh
+./01_server_init.sh 22 8G
+./02_install_nginx.sh your-domain.com
+./03_install_docker.sh
+./04_allow_cloudflare.sh
+```

+ 49 - 0
scripts/update_cloudflare_ips_for_nginx.sh

@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# output file
+OUTPUT_FILE="$1"
+OUTPUT_DIR=$(dirname "$OUTPUT_FILE")
+mkdir -p "$OUTPUT_DIR"
+
+# check root
+if [[ $EUID -ne 0 ]]; then
+   exit 1
+fi
+
+# Cloudflare IPs URL
+CF_IPV4_URL="https://www.cloudflare.com/ips-v4"
+CF_IPV6_URL="https://www.cloudflare.com/ips-v6"
+
+# write file header
+cat <<EOF > $OUTPUT_FILE
+# Cloudflare Real IP Configuration
+# Generated at: $(date)
+EOF
+
+# write IPv4 header
+cat <<EOF >> $OUTPUT_FILE
+
+# IPv4: $CF_IPV4_URL
+EOF
+
+# fetch & process IPv4
+curl -sL $CF_IPV4_URL | sed 's|^|set_real_ip_from |; s|$|;|' >> $OUTPUT_FILE
+
+# write IPv6 header
+cat <<EOF >> $OUTPUT_FILE
+
+# IPv6: $CF_IPV6_URL
+EOF
+
+# fetch & process IPv6
+curl -sL $CF_IPV6_URL | sed 's|^|set_real_ip_from |; s|$|;|' >> $OUTPUT_FILE
+
+# write file footer
+cat <<EOF >> $OUTPUT_FILE
+
+# Using CF-Connecting-IP to fetch real ip
+real_ip_header CF-Connecting-IP;
+EOF
+
+# reload nginx
+systemctl force-reload nginx

+ 39 - 0
scripts/update_cloudflare_ips_for_ufw.sh

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# check root
+if [[ $EUID -ne 0 ]]; then
+   exit 1
+fi
+
+# Cloudflare IPs URL
+CF_IPV4_URL="https://www.cloudflare.com/ips-v4"
+CF_IPV6_URL="https://www.cloudflare.com/ips-v6"
+
+# remove exist rules
+CF_RULES=$(ufw status numbered | grep '# Cloudflare' | grep -oP '\[\s*\K\d+(?=\])' | sort -rn)
+if [ -z "$CF_RULES" ]; then
+    echo "no rule should be deleted"
+else
+    for NUM in $CF_RULES; do
+        ufw --force delete $NUM
+    done
+fi
+
+# add rules for IPv4
+while read ip; do
+    if [[ ! -z "$ip" ]]; then
+        ufw allow proto tcp from $ip to any port 80 comment 'Cloudflare IPv4 HTTP'
+        ufw allow proto tcp from $ip to any port 443 comment 'Cloudflare IPv4 HTTPS'
+    fi
+done < <(curl -sL "$CF_IPV4_URL")
+
+# add rules for IPv6
+while read ip; do
+    if [[ ! -z "$ip" ]]; then
+        ufw allow proto tcp from $ip to any port 80 comment 'Cloudflare IPv6 HTTP'
+        ufw allow proto tcp from $ip to any port 443 comment 'Cloudflare IPv6 HTTPS'
+    fi
+done < <(curl -sL "$CF_IPV6_URL")
+
+# print latest rules
+ufw status numbered