Ollama 默认是仅本地访问,接口地址是:http://localhost:11434
开放外部访问需要设置两个环境变量:
OLLAMA_HOST=0.0.0.0
OLLAMA_ORIGINS=*
第一步,设置环境变量
macOS:
在终端中运行命令
launchctl setenv OLLAMA_HOST "0.0.0.0"
launchctl setenv OLLAMA_ORIGINS "*"
Windows:
打开“环境变量”配置框
添加两个用户变量:
Linux:
使用 systemctl 设置环境变量
调用 systemctl edit ollama.service 编辑 systemd 服务配置
在 [Service] 下方添加:
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=*"
第二步,重启 Ollama
环境变量配置完成后,重启 Ollama。
第三步,开放防火墙端口
Windows:
进入“高级安全 Windows Defender 防火墙” → “入站规则” → 新建规则 → 允许 TCP 端口 11434。
第四步,验证
获取本机局域网 IP。
Windows:ipconfig
Linux/macOS:ifconfig
访问网址:http://<ip>:11434
若返回 Ollama is running 则表示连接正常。

前几天实现了在 nginx 中使用 lua 实现远程鉴权,今天想试试在 IIS 中能不能实现相同的功能。查询资料发现需要使用 URL 重写和 HTTP 请求模块,没有深究。干脆使用 ASP.NET 中间件来实现吧。
在 StratUp.cs 的 Configure 方法中,或 Program.cs 文件中添加以下代码:
// 远程鉴权
app.Use(async (context, next) =>
{
var ip = context.Connection.RemoteIpAddress!.ToString();
var ua = context.Request.Headers.UserAgent.ToString();
var host = context.Request.Host.Host;
var uri = new Uri(context.Request.GetDisplayUrl()).PathAndQuery;
var client = new HttpClient();
client.Timeout = TimeSpan.FromSeconds(1); // 设置超时时间
try
{
var requestUrl = "https://鉴权地址/";
var requestMessage = new HttpRequestMessage(HttpMethod.Get, requestUrl);
requestMessage.Headers.Add("X-Real-IP", ip);
requestMessage.Headers.Add("User-Agent", ua);
requestMessage.Headers.Add("X-Forwarded-Host", host);
requestMessage.Headers.Add("X-Forwarded-Uri", uri);
// 发送请求
var response = await client.SendAsync(requestMessage);
// 检查响应状态码
if (response.StatusCode == HttpStatusCode.Forbidden)
{
// 如果返回403,则拒绝访问
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
await context.Response.WriteAsync("Access Denied");
}
else
{
// 如果返回其他状态码,则继续执行管道中的下一个中间件
await next();
}
}
catch (TaskCanceledException ex) when (ex.CancellationToken.IsCancellationRequested)
{
// 如果请求超时(任务被取消),则继续执行管道中的下一个中间件
await next();
}
catch
{
// 如果遇到错误,则继续执行管道中的下一个中间件
await next();
}
});
代码很简单,使用 HttpClient 发送请求,若返回 403 则拒绝访问,其它情况继续执行业务逻辑,超时或报错的情况按需修改即可。
若鉴权接口在私网中,建议将鉴权接口域名和私网 IP 添加到 hosts 文件中。

http {
...
lua_shared_dict cpu_cache 1m; # 定义共享字典用于缓存 CPU 使用率
access_by_lua_block {
local cpu_cache = ngx.shared.cpu_cache
local cache_time = cpu_cache:get("cache_time") or 0
local current_time = ngx.now()
if current_time - cache_time > 5 then -- 每 5 秒更新一次
local cpu_info = io.popen("top -bn1 | grep 'Cpu(s)'"):read("*all")
local cpu_usage = cpu_info:match("(%d+%.%d+) id") -- 获取空闲 CPU 百分比
local cpu_used = 100 - tonumber(cpu_usage) -- 计算使用率
cpu_cache:set("cpu_usage", cpu_used)
cpu_cache:set("cache_time", current_time)
end
local cpu_usage = cpu_cache:get("cpu_usage")
ngx.log(ngx.INFO, "CPU 使用率: " .. cpu_usage .. "%")
-- 将 cpu_usage 发送到远程鉴权接口,可根据服务器压力来决定是否拒绝一些不重要的请求
}
}
代码解析:
共享字典:使用 lua_shared_dict 定义一个共享字典 cpu_cache,用于存储 CPU 使用率和缓存时间。
获取 CPU 使用率:在 access_by_lua_block 中,检查缓存时间,如果超过 5 秒,则重新获取 CPU 使用率,并更新共享字典。
记录日志:使用 ngx.log 将 CPU 使用率记录到 Nginx 日志中。
注意事项:
确保 Nginx 配置中已经加载了 Lua 模块(如 ngx_http_lua_module)。
根据实际需求调整缓存时间,以平衡性能和数据的实时性。
尝试过使用 ifconfig 或 ip 命令获取网卡流量,在宝塔面板中失败了,怀疑是权限问题,有空再研究。临时方案是鉴权接口定时调用宝塔面板 API 或阿里云控制台 API 来获取 ECS 的 CPU 和带宽使用率。

在 access_by_lua_block 代码块中实现远程鉴权:
#鉴权-START resolver 223.5.5.5; # 使用公共 DNS access_by_lua_block { local http = require("resty.http") local httpc = http.new() httpc:set_timeout(500) -- 连接超时 local res, err = httpc:request_uri("https://鉴权地址/", { method = "GET", headers = { ["X-Real-IP"] = ngx.var.remote_addr, ["User-Agent"] = ngx.var.http_user_agent, ["X-Forwarded-Host"] = ngx.var.host, ["X-Forwarded-Uri"] = ngx.var.request_uri, }, ssl_verify = false, -- 禁用 SSL 验证 timeout = 500, -- 读取超时 }) if not res then ngx.log(ngx.ERR, "Failed to request: " .. err) end if res and res.status == 403 then ngx.exit(ngx.HTTP_FORBIDDEN) -- return ngx.redirect("https://一个显示403友好信息的页面.html") end } #鉴权-END
注意更改接口地址和友情显示 403 页面地址。
本示例仅捕获 403 状态码,500、408 等其它异常情况视为允许访问,请根据业务需求自行添加状态码的判断。
若超时也会进入
if not res then
代码块。建议将此代码部署在 nginx 主配置文件的 http 代码块中(宝塔面板中的路径:/www/server/nginx/nginx/conf/nginx.conf),如果你只想为单个网站鉴权,也可以放在网站配置文件的 server 块中。
若鉴权接口在私网中,建议将鉴权接口域名和私网 IP 添加到 hosts 文件中。
附
直接输出字符串
ngx.header.content_type = "text/plain"; ngx.say("hello world!")
输出到日志
ngx.log(ngx.ERR, "Response status: " .. res.status)
日志在网站的 站名.error.log 中查看。
宝塔面板查看方式:日志 - 网站日志 - 异常
若想获取服务器 CPU 使用率等信息并传递给远程鉴权接口,请参考此文。
常见问题
no resolver defined to resolve
原因:没有定义 DNS 解析器
解决方法:在 http 块或 server 块中添加
resolver 8.8.8.8 valid=30s;
,当然使用接入商自己的公共 DNS 可能更合适。unable to get local issuer certificate
原因:没有配置 SSL 证书信息
解决方法:添加 request_uri 参数:
ssl_verify = true, -- 启用 SSL 验证 ssl_trusted_certificate = "证书路径", -- 指定 CA 证书路径
或
ssl_verify = false, -- 禁用 SSL 验证
若您不想用 lua,可以用 nginx 原生自带的 auth_request 模块来实现。

鉴权方式有许多,譬如可以用 lua 的 access_by_lua 来实现,这里用 nginx 自带的 auth_request,虽然功能简单,但效率更高。
第一步,确保 nginx 已编译安装 auth_request 模块,见此文。
第二步,打开需要鉴权的网站的 nginx 配置文件,添加以下代码块:
#鉴权-START
location / {
auth_request /auth;
error_page 403 = @error403;
#PHP-INFO-START PHP引用配置,可以注释或修改
include enable-php-**.conf;
#PHP-INFO-END
}
location = /auth {
internal;
proxy_pass https://鉴权地址;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header User-Agent $http_user_agent;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_intercept_errors on;
#proxy_read_timeout 1s; # 超时会报 500
}
location @error403 {
#default_type text/plain;
#return 403 'forbidden';
return 302 https://一个显示403友好信息的页面.html;
}
#鉴权-END
一般放在所有的 location 之前。
这里自定义请求头 X-Forwarded-Host
与 X-Forwarded-Uri
用来传递 host 与 uri。API 应从 Header 中相应取值。
宝塔面板中是通过 include enable-php-**.conf;
的方式调用 PHP ,那么可以将此行移入上面的 location /
代码块中,因为此代码块能匹配所有的请求路径。
最后,若鉴权接口在私网中,将鉴权接口域名和私网 IP 添加到 hosts 文件中。

解析域名(非网站域名)、修改实例名称、主机名
设置阿里云(重要)
远程连接进入 ECS(若解析未生效可以先用 IP)(若新服默认使用 22 端口,可在阿里云控制台登录系统,或先在安全组临时放行 22 端口)
修复系统漏洞
将磁盘挂载到目录(fdisk、df 命令参考:https://xoyozo.net/Blog/Details/SSH)
安装宝塔面板(本文以宝塔面板方案为例,选择任何你喜欢的环境部署方案都行)。可以在阿里云控制台ECS实例页安装扩展程序
临时放行宝塔面板端口,进入宝塔面板(http方式),或用命令更改宝塔面板端口
配置面板 SSH、添加新的安全端口、面板设置
更改 SSH 默认端口(参:https://xoyozo.net/Blog/Details/change-default-port)
安装 nginx、PHP 等
配置 PHP 扩展(Redis、sqlsrv(注意选择兼容的版本)、memcached 及端口)
创建网站,配置网站(路径、伪静态等)
迁移网站文件(参:https://xoyozo.net/Blog/Details/SSH)
仔细对比新旧网站的配置文件(特别是 .php 的访问权限,参:https://xoyozo.net/Blog/Details/nginx-location-if)
设置写入目录(使用 rsync 同步的文件会同步用户和权限)
解析域名(先改 hosts 测试网站功能)
更改内网其它 ECS 上的 hosts
关闭原 ECS(能马上发现问题,不然等运行一段时间才发现问题就麻烦点)
设置 FTP
迁移“计划任务”
所有网站和软件的配置文件都要使用 WinMerge 进行对比
移除“宝塔面板-安全”和“阿里云-ECS-安全组”中不用的端口
再次检查阿里云设置
私网中若有 ECS 的 hosts 中域名直接绑定到私网 IP 的,做相应更改
其它:ERP添加到期提醒、WAF增加ECS、备份工具增加ECS
更多文章:

使用远程桌面连接时提示你的凭据不工作:
解决方法一:关闭 Windows Defender Credential Guard
打开组策略编辑器(gpedit.msc)
展开:计算机配置 - 管理模板 - 系统 - Device Guard,双击右侧的“打开基于虚拟化的安全”,改为“已禁用”
重启电脑
解决方法二【推荐】:使用其他远程桌面客户端
在 Microsoft Store 中查找“Microsoft 远程桌面”,或者点此安装
这个应用同样来自微软,使用方式与传统的远程桌面连接略有区别,如果你在 iPhone 或安卓上使用过,那么就能快速上手。
若要共享剪贴板,在“编辑电脑”中开启,并且在 设置 - 隐私与安全 - 文件系统 中允许“远程桌面”。
相对于传统的远程桌面连接,对高 DPI 兼容性不完美。

解析域名(非网站域名)、挂载磁盘(若有另购)、修改实例名称、主机名
设置阿里云(重要)
远程连接进入 ECS(若解析未生效可以先用 IP)(若新服默认使用 3389 端口,可先在安全组临时放行 3389 端口)
开启 Windows 防火墙(使用推荐设置)
Windows 更新、并在高级选项中开启(更新 Windows 时接收其它 Microsoft 产品的更新)
安装 IIS:服务器管理器-添加角色和功能-勾选“Web 服务器(IIS)”包括管理工具
建议勾选:
默认已勾选项
按需安装 IP 和域限制
跟踪(即“失败请求跟踪”)
请求监视器、日志记录工具、
按需安装 ASP
按需安装 ASP.NET 4.8(会同时勾选 .NET Extensibility 4.8、ISAPI 扩展、ISAPI 筛选器)
按需安装 WebSocket 协议
应用程序初始化(建议安装)
管理服务(用于 Web 部署)
细节:设置任务栏;设置桌面图标;个性化-颜色-勾选“标题栏和窗口边框”;设置输入法;
下载 URL 重写(文件名:rewrite_amd64_zh-CN.msi)
下载 MySQL Connector/NET(文件名:mysql-connector-net-8.0.19.msi)
下载 ASP.NET Core 运行时 Hosting Bundle(文件名:dotnet-hosting-*.*.*-win.exe)
下载 .NET 桌面运行时 Windows x64(文件名:windowsdesktop-runtime-*.*.*-win-x64.exe)
下载 Web Deploy(文件名:WebDeploy_amd64_zh-CN.msi)
服务:设置“ASP.NET State Service”自动启动
IIS 日志:路径(如 D:\wwwlogs),每小时(统一设置一个全局的就行了,不需要设置每个网站),按需勾选“使用本地时间进行文件命名和滚动更新”
IIS 导入证书:个人、允许导出证书。参
设置权限:设置网站所在分区(如 D 盘),安全,添加 IIS_IUSRS,全部拒绝(防止跨站)
添加用户:为每个网站创建用户(既能防止跨站,又能跟踪进程),密码不能改、不过期,仅隶属于 IIS_IUSRS,并添加到每个网站的根目录,若用户创建失败看这里。
创建网站:设置访问物理路径的用户;设置应用程序池的“标识”用户;编辑绑定:勾选需要服务器名称指示;检查域名是否绑全;设置写入目录;
重复上面两步
检查所有网站用户是否仅隶属于 IIS_IUSRS(在“组”页面双击 Users 和 IIS_IUSRS 查看成员)
在应用程序池列表页面检查 CLR 版本、管托管道模式和标识;在网站列表页面检查绑定和路径
设置“IP 地址和域限制”
废弃旧服时再次检查:IIS 中各功能设置、hosts、安装的应用程序、启动项、服务、防火墙等
解析各网站域名
其它:资源管理器-查看-选项-查看-去掉“始终显示图标,从不显示缩略图”前的勾
再次检查阿里云设置
在备份工具中添加该服务器的所有备份项
其它:到期日期提醒、
>> 关于域名解析
因各地域名解析生效时间不可控,一般国内域名 1 天内,国际域名 2 天内。
若网站数据库在 RDS、上传文件在 OSS,则解析 48 小时后直接停止原网站即可;(比较理想的)
文件上传到 ECS 的可使用 FTP 等工具定时同步文件,或直接停止原网站。(网友会遇到新文章中图片无法显示等问题)
还有一种方法是新网站提前解析一个备用域名,确保完全生效后再修改正式域名的解析,原网站无条件跳转到备用域名,如果数据库中有保存完整网址路径的,关闭原网站并解绑备用域名之后,进行批量替换。(缺点是可能会影响在搜索引擎的网站权重)
部分有定时器的网站要注意,如果两个网站的定时器都正常开启会导致意外的,需要停止其中一个网站的定时器。
当然每种方法都有优缺点,选择可以接受且方便的一种即可。
更多文章:

默认端口带来安全隐患,建议更改为 50000-60000 之间的端口号。
Windows 远程桌面(RDP)(3389)
在 Windows 防火墙中放行新端口:在“入站规则”中找到“Open RDP Port 3389”复制并粘贴该规则,修改端口和名称。
若没有这个规则:新建规则 - 端口 - TCP - 特定本地端口(填写新的端口号)- 允许连接 - 名称
如有其它防火墙或安全组也一并配置(如阿里云 ECS 的安全组)
打开注册表(regedit),展开到:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp,右侧双击“PortNumber”切换到“十进制”,将 3389 改为新端口号
重启生效
在防火墙和安全组中禁止原默认端口
SSH (22) 之 CentOS
从阿里云控制台登录服务器(如果未设置 root 密码则先设置),直接跳到第 4 步
在外部防火墙中放行新的端口号(如阿里云 ECS 的安全组)
在内部防火墙中放行新的端口号(如 firewalld 或 iptables),使用宝塔面板的直接在面板“安全”页面设置即可
打开 SSH 配置文件
sudo vi /etc/ssh/sshd_config
找到并编辑 Port 行的商品号并启用
#Port 22
重新加载使生效
sudo systemctl reload sshd
在防火墙和安全组中禁止原默认端口
建议使用 SSH 密钥对代替传统账号密码登录
FTP (21) 之 FileZilla Server Windows 版
一般地,在 Windows Defender 防火墙中是以添加应用 filezilla-server.exe 的方式允许的,所以不需要更改端口。如果以端口方式允许的,那么在入站规则中允许新的端口。
如有其它防火墙或安全组也一并配置(如阿里云 ECS 的安全组)
打开 Administer FileZilla Server,打开菜单 - Server - Configure - Server listeners,右侧窗口中将 Port 改为新端口(强烈建议将 Protocol 改为“Require explicit FTP over TLS”,即禁止 FTP 协议,改为使用 FTPS 协议)
从防火墙和安全组移除 21 端口
FTP (21) 之 Pure-Ftpd(宝塔面板)
在防火墙中放行新的端口号(如阿里云 ECS 的安全组)
进入宝塔面板,打开“安全”,添加端口规则 TCP
在宝塔面板中进入软件商店,找到 Pure-Ftpd 并打开,切换到“配置修改”,搜索“Bind”,删除开头的“#”,将端口号 21 改为新端口号,保存(强烈建议将 TLS 项改为 2,即禁止 FTP 协议,仅允许 FTPS 协议)
切换到“服务”选项卡,点击“重启”
从防火墙和安全组移除 21 端口
MySQL (3306) 之阿里云云数据库 RDS MySQL 版
打开控制台 RDS 实例页,左侧菜单点击“白名单与安全组”,切换到“安全组”查看正在使用的安全组ID
(若使用了安全组)打开控制台 ECS 首页,左侧菜单点击“安全组”,找到这个安全组,放行新的端口
打开控制台 RDS 实例页,左侧菜单点击“数据库连接”,点击“修改连接地址”,在弹出框中修改端口
从防火墙和安全组移除原端口(确保没有其它实例正在使用此端口)
PolarDB (3306)
打开控制台 PolarDB 集群实例页,左侧菜单点击“集群白名单”,切换到“安全组”查看正在使用的安全组ID
(若使用了安全组)打开控制台 ECS 首页,左侧菜单点击“安全组”,找到这个安全组,放行新的端口
打开控制台 PolarDB 集群实例页,左侧菜单点击“基本信息”,点击“主地址”和“集群地址”的“配置”,在“网线信息”中点击“更多”更改端口
从防火墙和安全组移除原端口(确保没有其它实例正在使用此端口)
MSSQL (1433) 之阿里云云数据库 RDS SQL Server 版
打开控制台 RDS 实例页,左侧菜单点击“白名单与安全组”,切换到“安全组”查看正在使用的安全组ID
(若使用了安全组)打开控制台 ECS 首页,左侧菜单点击“安全组”,找到这个安全组,放行新的端口
打开控制台 RDS 实例页,左侧菜单点击“数据库连接”,点击“修改连接地址”,在弹出框中修改端口
从防火墙和安全组移除原端口(确保没有其它实例正在使用此端口)
Redis (6379) 之阿里云云数据库 Redis 版
打开控制台 Redis 实例页,左侧菜单点击“白名单设置”,切换到“安全组”查看正在使用的安全组ID
(若使用了安全组)打开控制台 ECS 首页,左侧菜单点击“安全组”,找到这个安全组,放行新的端口
打开控制台 Redis 实例页,在“连接信息”中点击“修改连接地址”,在弹出框中修改端口
从防火墙和安全组移除原端口(确保没有其它实例正在使用此端口)
宝塔面板 (8888)
在防火墙中放行新的端口号(如阿里云 ECS 的安全组),或直接在私网其它 ECS 上的浏览器上直接访问原 8888 端口的地址
进入宝塔面板,打开面板设置,切换到“安全设置”页,找到“面板端口”,点击“设置”
在防火墙和安全组中禁止原默认端口
IIS 管理服务(Web 部署)(8172)
在 Windows 防火墙中放行新端口:在“入站规则”中找到“Web 管理服务(HTTP 流量入站)”因其为预定义规则且复制也无法修改,所以按其设置新建一个,并指定新的端口。
如有其它防火墙或安全组也一并配置(如阿里云 ECS 的安全组)
打开 IIS 管理器 - 管理服务,右侧停止,左侧修改端口,右侧启动
VS 中发布配置修改“服务器(E)”项添加端口
在防火墙和安全组中禁止原默认端口
