0%

当我们搭建OpenVpn服务端后,用OpenVpn客户端连接到服务端后,客户端可以访问服务端的vpn地址(如10.8.0.1),可以访问服务端的内网地址(如192.168.0.28)。服务端可以访问客户端的vpn地址(如10.8.0.6),但是无法访问客户端的内网地址(如192.168.1.10)。本文将在 这篇 文章的基础上,让服务端可以访问客户端的内网地址,实现不同网段的两台机器无感互通。

如下图所示:

这篇 文章中,我们已经能从vpn客户端访问vpn服务端的内网ip地址、vpn ip地址,以及内网其他机器的内网ip地址(通过在vpn服务端开启ip转发并设置iptables的SNAT转发),以及从vpn服务端访问vpn客户端的vpn ip地址(如果无法访问,请在客户端和服务端都添加防火墙规则,允许这些ip地址以及相应协议的访问,比如ping的icmp协议)。

现在我们要实现从vpn服务端访问vpn客户端的内网地址 192.168.1.10,从而打通vpn服务端和客户端的跨网段访问。

下面将用Ubuntu22.04作为vpn服务端以及vpn客户端。

阅读全文 »

本文将在Ubuntu22.04服务器安装OpenVpn服务端,并在Windows10安装OpenVpn客户端。

安装OpenVpn和Easy-RSA

Easy-RSA主要用来生成CA证书,服务端证书和key,客户端证书和key。先登录Ubuntu服务器,然后用root身份执行下文的命令。

1
2
3
4
5
sudo apt update
sudo apt install openvpn easy-rsa

# 安装完可以查看下openvpn版本
openvpn --version

制作所需的证书

执行如下命令

1
2
3
4
5
6
7
8
9
10
cd /usr/share/easy-rsa

# 拷贝一份vars文件
cp vars.example vars

# 编辑vars文件
vim vars

# 在最后一行添加如下内容,这个 KEY_NAME 下文会用到,请记住
export KEY_NAME="myserver"

开始制作证书

阅读全文 »

本文以MacOS docker desktop为例。

下载安装MacOS版docker desktop

  1. 下载地址

  2. 双击安装 Docker.dmg

创建etcd3目录

  1. 创建一个目录用于运行docker etcd3,如:/path/to/etcd3

  2. 在如上目录内创建 docker-compose.yml 文件,内容如下:

阅读全文 »

本文将简要介绍火爆全网的NLP对话AI:ChatGPT的注册使用教程。

1、使用dl工具,使用全局模式,选us节点

2、打开Chrome浏览器无痕模式

3、访问 OpenAI ChatGPT 入口:https://chat.openai.com/auth/login

4、填写非国内邮箱地址

5、使用短信接收平台验证:https://sms-activate.org/

6、注册完成后,登录截图如下:

JS装饰器是ES7的新语法,浏览器,nodejs不一定支持,需要babel转译。

实验环境

创建一个目录test,结构为:

1
2
3
4
5
6
7
.
├── .babelrc
├── .npmrc
├── lib
├── package.json
└── src
└── index.js

babel的装饰器配置:

阅读全文 »

元编程

什么是元编程?

用代码来生成代码,或者说,用程序来生成程序,就叫元编程。Python能通过反射实现元编程。

什么是元类?

与元编程相关的一个概念是元类。什么是元类呢,具体到Python,用来创建类的类,就叫元类。元类是制造类的工厂。

在Python中,一个普通类创建出来的东西是类的实例,实例是一个对象。而元类也是一种类,它创建出来的东西是另一个普通类,普通类也是一个对象(Python中一切皆对象),然后这个普通类,又可以创建出类的实例。所以说,元类是类的类。它们的构建过程如下图:

Python中:

1、所有非object类都继承自object类(包括type)
2、所有类的类型都是type(包括type、object、元类)
3、type类继承自object(符合第1句)

虽然type也继承自object,但是我们自己写的类,继承自object与继承自type,会有些不同。

type元类

type这个类,不仅可以获取Python中对象的类型,比如type(123),会告诉你123是int类型(int也是类)。

type也可以作为元类,来构建其他类。语法是:

type(name, bases, dict) -> a new type 返回一个新的类型

阅读全文 »

属性:这里表示类(或类的实例)中的变量与方法的统称。

所以搜索顺序包括:类的属性搜索顺序、类的实例的属性搜索顺序。

下面是所有魔术方法同时出现的情况下,类或实例的属性搜索顺序。

默认搜索顺序

对于类,比如查找A.x。A是类,x是类的属性。

类属性的默认搜索顺序:A自己的x(即A的属性字典__dict__) ⟶ A的父类的x [1] ⟶ 父类的父类的x… ⟶ object的x

对于类的实例,比如查找a.x。a是A的实例,x是实例的属性。

实例的默认搜索顺序:a自己的x(即a的属性字典__dict__)⟶ a从父类的构造方法(__new__, __init__)继承来的属性 ⟶ A自己的x ⟶ A的父类的x [1] ⟶ 父类的父类的x… ⟶ object的x

[1]:

如果A是单继承,直接不断向上找父类。如果A是多继承,由Python3的mro生成一个有序的继承列表,依次找父类。

相关的魔术方法

与搜索顺序相关的魔术方法有:

1、反射相关的:__getattr__, __setattr__, __delattr__, __getattribute__

2、描述器相关的:__get__,__set__,__delete__

下面是所有魔术方法同时出现的情况下,类或实例的属性搜索顺序:

阅读全文 »

装饰器

要讲清楚装饰器,首先要知道一些前置概念。下文涉及到这些概念的地方,会展开讲述。

什么是装饰器?

装饰器是一种AOP(面向切面编程)的设计模式。

面向对象编程往往需要通过继承或组合依赖等方式调用一些功能,这样可能造成代码的重复,增加了耦合。

而AOP可以在需要的类或方法上切入,切入点可以增强功能,让调用者与被调用者解耦。

这种不修改原来的业务代码,给程序动态添加(或修改)功能的技术,就是装饰器

装饰器可用于日志记录、监控、参数检查等地方。比如业务函数中不应该包含与业务无关的功能,那么可以构建一个logger装饰器,对业务函数增加日志功能。并且logger装饰器可以是通用的,需要日志功能的地方,都可以使用logger装饰器,达到复用的目的。

装饰器的分类

无参数装饰器:无参数装饰器实现的关键是“闭包”,即嵌套函数与自由变量。

带参数装饰器:带参数装饰器实现的关键是“柯里化”,多层嵌套函数可以实现柯里化。

什么是闭包?

在讲什么是闭包前,需要先讲一个概念:自由变量。什么是自由变量呢?

未在本地作用域中定义,就是出现在嵌套函数中,定义在某函数的外层函数的作用域中的变量,叫自由变量

如果某函数(即内层函数)引用了外层函数的自由变量,这样就形成了闭包

阅读全文 »

描述器

什么是描述器?

一个类中定义了如下一个或多个魔术方法,这个类的实例就是描述器:

__get__,__set__,__delete__

通常需要两个类来构建描述器:

如果类B的类属性x,指向另一个类A的实例。被指向的A的实例就是描述器对象。B.x是描述器,B也是描述器的属主(owner)。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
class A:
def __get__(self, instance, owner):
pass

def __set__(self, instance, value):
pass

def __delete__(self, instance):
pass

class B:
x = A() # x是描述器
pass

类属性的值,通常是一些已有类型的对象,比如字符串、列表等。

当使用了描述器,类属性就指向一个描述器对象,描述器通过三个魔术方法,可以自定义属性的行为。

阅读全文 »