原理:读取系统相关登入、安全日志,调用防火墙禁止频繁登入失败的IP。

目的:

Nginx 配置 SSL,透传到 后端。 根据不同的域名转发到不同的后端。

配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
user  root;
worker_processes auto;
events {
worker_connections 1024;
}
stream {
log_format basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$ssl_preread_server_name" "$name"';
access_log /var/log/nginx/stream_access.log basic;

map $ssl_server_name $name {
# hostnames;
default app_default_backend;
app.ownding.com.cn app1_backend;
www.ownding.com.cn app2_backend;
}
upstream app1_backend {
server 192.168.0.117:30080 weight=5 max_fails=1 fail_timeout=10s;
}
upstream app2_backend {
server 192.168.0.117:30081 weight=5 max_fails=1 fail_timeout=10s;
}
upstream app_default_backend {
server 192.168.0.117:30081;
}
server {
listen 31180 ssl;
ssl_certificate /home/cert/scs1687747992522__.ownding.com.cn_server.crt;
ssl_certificate_key /home/cert/scs1687747992522__.ownding.com.cn_server.key;
proxy_pass $name;
}
}

遇到的错误:

1
curl: (60) SSL certificate problem: unable to get local issuer certificate

说明 curl 在验证服务器证书时找不到对应的 CA 根证书,也就是说你的系统没有信任该网站所使用的证书签发机构(CA)。


✅ 你有根证书,可以手动添加到 Ubuntu 系统的信任库中,以下是完整解决步骤:


🔧 步骤 1:确认你有 CA 的根证书文件

你可能有一个 .crt.pem 文件,例如:

1
my-ca.crt

如果没有,请从你的证书颁发机构获取。


🔧 步骤 2:将证书复制到系统证书目录

以 root 权限执行以下命令:

1
sudo cp my-ca.crt /usr/local/share/ca-certificates/

注意:

  • 证书文件名必须是 .crt 后缀;
  • 推荐放在 /usr/local/share/ca-certificates/ 目录下。

🔧 步骤 3:更新系统证书信任库

运行以下命令更新系统的 CA 信任列表:

1
sudo update-ca-certificates

输出类似:

1
2
3
4
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

这表示你的证书已成功加入系统信任链。


✅ 验证是否生效

再次运行你的 curl 命令:

1
curl -v https://vpn.ownding.xyz

如果一切正常,就不会再报 unable to get local issuer certificate 错误了。


📌 补充说明

如果你使用的是自签名证书:

  • 你也需要把服务端使用的 服务器证书本身 添加为信任证书,或者在客户端使用 --cacert 指定它:
1
curl --cacert /path/to/server.crt https://vpn.ownding.xyz

🛡️ 安全提示

  • 不要随意添加不可信的证书到系统信任库,这会带来安全风险。
  • --insecure(即 -k)参数虽然能绕过证书验证,但不建议在生产环境中使用。

✅ 总结

问题 解决方式
curl 报错 unable to get local issuer certificate 将根证书添加到系统信任库
有根证书怎么处理? 复制到 /usr/local/share/ca-certificates/ 并运行 update-ca-certificates

  • 1、在某一个客户端(路由器/网关)端生成 ipv6 子网

使用命令:tailscale debug via 7 192.168.6.0/24

其中 7siteID,可自行填写 0-60000之间的数值。

生产 ipv6 子网后,需要在客户端重新宣告子网。

tailscale set --advertise-routes=ipv6子网

openwrt

  • 2、在 headscale 服务端允许 子网

我使用 docker 部署的 headscale 服务端,使用如下命令开启子网。

docker exec headscale headscale routes enable -r 2

openwrt

  • 3、根据 计算方法获取 下挂设备的 ipv6地址:

比如 192.168.4.146 对应的地址 ipv6 地址是 :fd7a:115c:a1e0:b1a:0:7:c0a8:692

参考链接: http://www.ownding.com/2025/06/05/Tailscale-4via6-%E5%8A%9F%E8%83%BD-IP%E5%9C%B0%E5%9D%80%E8%BD%AC%E6%8D%A2%E8%A7%84%E5%88%99/

  • 4、测试 ipv6 地址访问

ipv6

问题:

点击 Trae AI 的“登入”,正常情况下,会自动打开浏览器进行登入,登入成功后浏览器会通知 Trae 登入完成,然后完成登入。 但是此次点击“登入”一直无法打开浏览器。
同时可扩展到其它软件点击登入后无法调用到windows系统浏览器的情况。

Trae AI

原因

之前安装过 夸克网盘(后来删除),被修改了注册表
计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
ProgId 的值为 QuarkHTM 导致无法启动 Edge 浏览器。

解决

将注册表中 计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoiceProgId 值修改为 MSEdgeHTM

regi

问题:

使用 ctr image import a.tar 后,crictl 查看没有显示刚刚导入的镜像。但是使用 ctr i list 可以查看镜像,不过也看不到 crictl 中的镜像。

原因:

使用的containerd不同导致的。

解决:

导入时指定k3s的containerd,
ctr -n k8s.io -a /run/k3s/containerd/containerd.sock image import app2.tar

注意:

当tar包没有tag信息时,导入之后,无报错,errno 为0,但是 通过 ctr images ls 查看却没有相关的镜像。这种情况,需要添加 --digests=true 来导入:
ctr image import --digests=true <path/to/images/file>

问题描述

执行任何 kubectl 命令时都会报错,比如执行 kubectl get node 命令时提示错误信息: Unable to connect to the server: x509: certificate has expired or is not yet valid

证书有效期查询:

1
for i in `ls /var/lib/rancher/k3s/server/tls/*.crt`; do echo $i; openssl x509 -enddate -noout -in $i; done

官网方法:

下面的命令不能更新 server-ca.crt ,可以轮换的证书:admin、api-server、controller-manager、scheduler、k3s-controller, k3s-server, cloud-controller, etcd, auth-proxy, kubelet,kube-proxy

1
2
3
4
5
6
7
8
# 停止 K3s
systemctl stop k3s

# 轮换证书
k3s certificate rotate

# 启动 K3s
systemctl start k3s

其它方法:

1
2
3
4
5
6
7
8
9
10
11
#删掉 secret k3s-serving
kubectl --insecure-skip-tls-verify -n kube-system delete secrets k3s-serving

#删掉 系统中的文件dynamic-cert.json
rm -f /var/lib/rancher/k3s/server/tls/dynamic-cert.json

#删掉目前k3s 进程,可以不用该步骤
#sudo /usr/local/bin/k3s-killall.sh

#重启 k3s 进程
sudo systemctl restart k3s

验证:

  • 1、将系统时间设置成证书快到期前1个月,然后重启k3s
  • 2、重启后浏览证书时间,发现证书的有效期自动延期1年,server-ca证书延期到10年
  • 3、再将时间设置成30年后,使用kubectl命令出现证书错误,但是部署的程序仍可以访问
  • 4、证书过期后,使用 systemctl restart k3s 命令,会卡住
  • 5、证书过期后,将时间设置成证书过期前的时间,程序恢复正常

长时间证书的简单方法

  • 1、将服务器时间调整到30年后
  • 2、更新证书
  • 3、调整到当前的时间

场景:

用户访问-----haproxy(docker部署)-----Nginx前端(docker部署)-----K8S后端
使用K8S部署的后端需要获取用户访问的IP地址(用户使用终端的IP)。

解决方案

用户访问时,在Haproxy处添加添加一个自定义的X-Real-IP请求头,后端通过这个请求头获取用户真实IP。

HTTP

只需要配置Haproxy即可,不用修改Nginx配置,Haproxy配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
global
log 127.0.0.1 local0
daemon
defaults
log global
mode tcp
option abortonclose
option redispatch
option forwardfor except 127.0.0.0/8
retries 3
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
frontend admin_stats
bind :8033
mode http
stats enable
option httplog
maxconn 10
stats refresh 30s
stats uri /admin
stats auth admin:123123
stats hide-version
stats admin if TRUE
frontend header_front
bind *:32297
mode http
option forwardfor
acl android-browser hdr_reg(User-Agent) -i Android
use_backend app_backend if android-browser
default_backend pc_backend
backend app_backend
mode http
server mom 172.16.30.52:32298 check
http-request set-header X-Real-IP %[src]
backend pc_backend
mode http
server mom-app 172.16.30.52:32298
http-request set-header X-Real-IP %[src]

haproxy 配置中添加 option forwardforhttp-request set-header X-Real-IP %[src]

HTTPS

如果使用HTTPS访问,那么需要同时修改Haproxy配置及Nginx配置。
Haproxy配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

global
log 127.0.0.1 local0
daemon
defaults
log global
mode tcp
option abortonclose
option redispatch
#option forwardfor except 127.0.0.0/8
retries 3
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
frontend admin_stats
bind :8033
mode http
stats enable
option httplog
maxconn 10
stats refresh 30s
stats uri /admin
stats auth admin:123123
stats hide-version
stats admin if TRUE
frontend header_front
bind *:32295
mode http
option forwardfor
acl android-browser hdr_reg(User-Agent) -i Android
use_backend app_backend if android-browser
default_backend pc_backend
frontend https_frontend
bind *:32297
mode tcp
acl tls req.ssl_hello_type 1
tcp-request inspect-delay 5s
tcp-request content accept if tls
default_backend pc_https_backend
backend app_backend
mode http
server mom 172.16.30.52:32298 check
http-request set-header X-Real-IP %[src]
backend pc_backend
mode http
server mom-app 172.16.30.52:32298
http-request set-header X-Real-IP %[src]
backend pc_https_backend
mode tcp
server mom-https-app 172.16.30.52:32296 send-proxy-v2

使用mode tcp以及send-proxy-v2进行透传。

Nginx配置示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

#user nobody;
worker_processes 1;
error_log /var/log/nginx/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;
log_format main '$proxy_protocol_addr - $remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/logs/nginx/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 443 ssl proxy_protocol;
server_name webServer;
ssl_certificate /home/cert/6030147_wx.xxx.com.pem;
ssl_certificate_key /home/cert/6030147_wx.xxx.com.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!NULL:!aNULL:!ADH:!3DES:!RC4;
ssl_prefer_server_ciphers on;
autoindex_localtime on;
client_max_body_size 1200M;
add_header X-Content-Type-Options nosniff;
add_header Strict-Transport-Security "max-age=315360; includeSubdomains;";
add_header X-XSS-Protection "1; mode=block";
location / {
root html;
index index.html index.htm;
}
location ^~/api/ {
proxy_read_timeout 300s;
proxy_pass http://172.16.30.52:32299/api/;
proxy_set_header X-Real-IP $proxy_protocol_addr;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

nginx.conf 中添加 proxy_protocol以及proxy_set_header X-Real-IP $proxy_protocol_addr;

后端代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
@RequestMapping("/api")
public class IpController {
@GetMapping("/getRealIp")
public String getRealIp(HttpServletRequest request) {
// 获取X-Real-IP请求头
String realIp = request.getHeader("X-Real-IP");
// 打印到控制台
System.out.println("X-Real-IP: " + realIp);
// 返回响应
return "X-Real-IP: " + realIp;
}
}

C# 与 MAtlab 混合编程

本文最初2014年发表在新浪博客,由于博客关闭计划将其搬移到本网站。

本文说明如何使用matlab和.net进行混合编程。包括:

  • 1、使用Matlab2010b&VS2010,vb.net编程(下文A部分)
  • 2、使用 Matlab 2017b & VS Community2017,C#混合编程。注意c#程序使用.net4.0编译(下文B部分)
  • 3、在.net(C#,vb)中如何处理m文件返回的多个结果
  • 4、MWArray结果的下标注意事项

A 部分

版本:Matlab2010b&VS2010
Matlab中需要以m文件Function形式,要有输出

  • 1、在Matlab中输入

deploytool
将编写好的函数文件拖入下图中的位置即可,编译的时候选择 .NET DLL

文件位置

  • 2、编译后,在VS中引用
    引用MWArray.dll(在Matlab安装路径)

dll引用

  • 3、引用Matlab生成的dll文件

dll引用2

  • 4、用记事本打开Class_VB.cs

在第一步时,你Class名称。在Matlab生成的文件路径下

class路径

  • 5、引用

引用

引用2

上面两幅图,第一幅是Class_VB.cs文件内容,第二幅是在VB.NET 中的引用。

  • 6、CPU选择(如果都是x86,可忽略;我Matlab/VS版本为64位的)

CPU

  • 7、编写代码运行

运行

OK,基本功能实现!

B 部分

版本:Matlab 2017b & VS Community2017

  • 1、需要安装 MATLAB Compiler和MATLAB Compiler SDK
  • 2、输入deploytool

Compiler

选Library Compiler

  • 3、选.Net Assembly,选Runtime included in package会将matlab的runtime打包。这样我们就可以在其它电脑上运行这个程序了。见下图

Compiler2

  • 4、点击 Save,见上图
  • 5、点击Package,见上图
  • 6、新建C#或VB.Net工程,注意.Net版本要用4.0版。需要引用MWArray.dll,以及上面生成的TcFigData.dll
  • 7、编译。Debug的时候选AnyCPU。打包后会自动生成一个cs文件,就是你打包时填写的Class Name对应的cs文件。我这里是tcFig.cs,里面包含函数调用的方法。

C#代码示例:

CSharp

上图包含m文件的函数结构,以及m文件多个结果返回的处理方法。
输出结果:

CSharp2

其中9331是301*31的cell。

  • 8、安装。在其它电脑上先安装matlab runtime,在for_redistribution文件夹里(前提是你打包的时候选了Runtime included in package)

程序文件夹

9、运行你编写的.net程序

使用Matlab如何画出上面的箱线图群组?

本篇原先在2012年发表在新浪博客,因为后面博客关闭服务,转移到这里。
箱线图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
示例:
data = rand(20,24)

month = repmat({'jan' 'feb' 'mar' 'apr' 'may' 'jun' 'jul' 'aug' 'sep' 'oct' 'nov' 'dec'},1,2);

simobs = [repmat({'sim'},1,12),repmat({'obs'},1,12)];

boxplot(data,{month,simobs},'colors',repmat('rb',1,12),'factorgap',[5 2],'labelverbosity','minor');

另一种方法是利用不同坐标使用hold on在同一幅图上画箱线图

% Boxplot for the observed temperature from January to December

Temp_O = [Jan_O, Feb_O, Mar_O, Apr_O, May_O, Jun_O, Jul_O, Aug_O, Sep_O, Oct_O, Nov_O, Dec_O];

position_O = 1:1:12;

% Define position for 12 Month_O boxplots

box_O = boxplot(Temp_O,'colors','b','positions',position_O,'width',0.18);

set(gca,'XTickLabel',{' '}) % Erase xlabels

hold on % Keep the Month_O boxplots on figure overlap the Month_S boxplots

% Boxplot for the simulated temperature from January to December

Temp_S = [Jan_S, Feb_S, Mar_S, Apr_S, May_S, Jun_S, Jul_S, Aug_S, Sep_S, Oct_S, Nov_S, Dec_S];

position_S = 1.3:1:12.3; % Define position for 12 Month_S boxplots

box_S = boxplot(Temp_S,'colors','r','positions',position_S,'width',0.18);



hold off % Insert texts and labels

箱线图2

0%