说在前面的话......
我希望能在公网直接访问我的Stable Diffusion WebUI,虽然说可以直接通过端口隐射或者内网穿透的方式引出来,但是由于WebUI本身是不带身份验证的,万一被某些无聊的人乱搞就不好了。
于是,我就想到用Nginx做反向代理,并且加入基本身份验证。也就是你打开网站的时候浏览器会弹出一个窗口要你填写身份信息进行认证。这样做的话,相对而言比较省事,不需要去增加功能和代码。
所需软件/工具
- Stable Diffusion WebUI
- FRP内网穿透工具
- Nginx
- HAproxy(如果有多个服务需要同时访问的话)
Stable Diffusion配置允许外部访问
在Stable Diffusion的目录找到webui-user.sh
文件,取消注释export COMMANDLINE_ARGS=""
,加上--listen
。
例如:
export COMMANDLINE_ARGS="--xformers --enable-insecure-extension-access --listen"
然后按照常规方式启动Stable Diffusion:
./webui.sh
配置FRP内网穿透
下载FRP后,解压,frps
是服务端,配置文件为frps.toml
,frpc
是客户端,配置文件为frpc.toml
。
服务端配置文件如下:
bindPort = 7000
auth.token = "your_passwd"
bindPort
是服务器监听端口。auth.token
是设置的连接密码。
客户端配置文件如下:
serverAddr = "172.16.0.1"
serverPort = 7000
auth.token = "your_passwd"
[[proxies]]
name = "Stable_Diffusion"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7860
remotePort = 7860
serverAddr
是服务器的IP地址。serverPort
是服务器设置的端口,需要和服务器保持一致。auth.token
是自定义的密码,需要和服务器保持一致。localIP
是要访问服务的本地IP。localPort
是本地服务的端口。remotePort
是把本地服务暴露出去在外面访问的端口。
所有相关文件位于同一目录,设置好后,服务端运行frps:
./frps -c ./frps.toml
客户端运行frpc:
./frpc -c ./frpc.toml
注意,这一步可以防火墙放行相关端口看看是否成功,但是弄完之后一定要关掉这个端口!
配置Nginx反向代理
配置基础身份验证
为了添加基础身份验证,需要生成一个密码文件。使用htpasswd
工具来创建这个文件。如果没有安装htpasswd
,可以通过安装 apache2-utils
包来获得:
apt install apache2-utils
然后,创建一个密码文件,并添加一个用户:
sudo htpasswd -c /etc/nginx/.htpasswd user
配置Web服务器配置文件
Web服务器配置文件内容如下:
server {
server_name yourdomain.example.com;
listen 10086 ssl;
listen [::]:10086 ssl;
ssl_certificate /path/to/your/cert.pem;
ssl_certificate_key /path/to/your/certkey.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Host $host;
client_max_body_size 20m;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
location / {
proxy_pass http://127.0.0.1:7860/;
}
location ~ /\.(?!well-known) {
deny all;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
log_not_found off;
access_log off;
}
}
以上是模板,要做以下修改:yourdomain.example.com
填你自己的域名。/path/to/your/cert.pem
填你服务器证书的位置。/path/to/your/certkey.key
填你服务器证书私钥路径。
保存为你自己想要的名称.conf并且放到/etc/nginx/http.d/
,例如/etc/nginx/http.d/neko.conf
。
重启Nginx
systemctl restart nginx
如果你按照我这样配置完成后,理论上访问https://yourdomain.example.com:10086
并且输入用户和密码验证身份后,即可看到你的Stable Diffusion WebUI了。
哦对了,别忘了添加域名的DNS解析记录。
配置HAproxy实现端口复用(可选)
如果你的服务器像我一样运行了多个不同的服务,并且你有域名的话,就可以用这个方法实现端口复用。也就是都走443端口进行访问。
这里我贴出来我的HAproxy配置文件:
#---------------------------------------------------------------------
# 全局设定部分
#---------------------------------------------------------------------
global
defaults
log global
option dontlognull
option http-server-close
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
# 定义DNS解析器
#---------------------------------------------------------------------
resolvers dns1
nameserver internal-dns 1.1.1.1:53
resolve_retries 3
timeout resolve 10s
timeout retry 10s
hold other 30s
hold refused 30s
hold nx 30s
hold timeout 30s
hold valid 10s
hold obsolete 30s
#---------------------------------------------------------------------
# 接管HTTP流量实现302跳转HTTPS
#---------------------------------------------------------------------
frontend http
bind :80
#accept-proxy
mode http
redirect scheme https code 302 if { hdr(Host) -i www.nekopara.uk } !{ ssl_fc }
redirect scheme https code 302 if { hdr(Host) -i sd.nekopara.uk } !{ ssl_fc }
#---------------------------------------------------------------------
# 通过SNI Proxy对HTTPS流量实现四层转发
#---------------------------------------------------------------------
frontend https_proxy
mode tcp
bind :443
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl is_www.nekopara.uk req_ssl_sni -i www.nekopara.uk
use_backend www.nekopara.uk if is_www.nekopara.uk
acl is_sd.nekopara.uk req_ssl_sni -i sd.nekopara.uk
use_backend sd.nekopara.uk if is_sd.nekopara.uk
backend www.nekopara.uk
mode tcp
balance roundrobin
option tcp-check
server ddns-1 org.nekopara.uk:3939 resolvers dns1 resolve-prefer ipv4 check send-proxy
server backup-server 127.0.0.1:8443 backup
backend sd.nekopara.uk
mode tcp
balance roundrobin
option tcp-check
server backup-server 127.0.0.1:10086
其中,www.nekopara.uk
是我博客的主域名,而sd.nekopara.uk
则是我自己要运行的Stable Diffusion WebUI服务。
这样一设置,我就可以让我的好几个不同的Web服务一起在443端口访问了,也就是不需要加端口了。
要注意一点,这里的端口号是要填写Nginx反代出来的端口号,也就是10086
,如果填FRP穿透出来的端口号,两个结果,要么无法访问,要么所有人都可以访问。一定要注意!
最终效果
访问时会弹出身份认证:
不认证不给访问:
认证成功后进入界面:
Nice!