BackIconPython SS Server

2021年3月30日

Openai logomark

Hamster1963

前言

这个学年学校把宽带运营商从之前的联通大哥哥换成了如今的电信小弟弟,使用体验可谓一落千丈,最主要的原因是电信不再像联通提供拨号上网的账号和密码,改成了强制使用天翼校园的程序来进行认证上网,而且限制只能一台设备在线,这直接搞垮了宿舍内的一堆需要联网的设备,首先想到的是通过电脑先连接在共享给路由器,感谢这位兄弟提供的方法@task138,但是转念一想,既然学校内覆盖了校园网,那是否可以使用电脑搭建服务器从而达到在校园网范围内手机或者 iPad 都可以上网呢?这就是今天讨论的方法。

⚠️
此方法仅限交流,请勿在保密场所使用。
此项目可实现:
自动获取本机局域网地址并写入配置文件。
自动获取本机局域网地址并写入配置文件。
开启时显示各项配置参数,帮助使用者配置代理软件。
开启SS代理服务器,出错时显示错误弹窗。

原理与改进

开启SS代理服务器部分参考了GitHub上的shadowsocks-libqss项目,需要使用者手动填写config文件,使用起来学习成本有一点高,且如果没有成功运行也没有错误提示,所以使用python编写一个小脚本改进一下,以达到上述的功能。

使用方法

windows开启服务器

想开启SS代理服务器十分简单,如果不想更改默认的端口、密码、加密方式,可以直接双击使用 开启SS代理服务器.exe,打开后根据弹窗配置自己的代理软件,安卓小飞机,苹果小火箭,windows使用clash,macOS使用surge。

一切顺利后应该是这样的界面

ios使用小火箭连接

在小火箭中点击右上角加号,类型选择Shadowsocks,根据配置弹窗中的信息,填入相关配置,混淆与插件为空。如图:

macos使用surge连接

打开surge面板,在策略中选择添加

填入配置信息,出站选择全局代理即可

surge教程到此结束

程序编写

我们的目标其实很简单,就是获取当前IP地址并且写入到config文件中,并在启动服务器时有弹窗包含主要配置信息提醒用户。

获取ip地址

这是一个很通用的获取本机局域网ip地址的方法,代码如下:

#获取实时IP地址
def get_host_ip():
    """
    查询本机ip地址
    :return: ip
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip

将ip地址写入配置文件

配置文件的类型是json,在python中我们可以很轻松地修改json文件内的值,只需要知道key和value的对应关系即可,代码如下:

#将IP地址写入json文件

filename = 'config.json'
with open(filename, 'r') as f:
    data = json.load(f)
    data['server'] = get_host_ip() # <--- 添加实时ip地址.

os.remove(filename)
with open(filename, 'w') as f:
    json.dump(data, f, indent=4)

由于上面的 get_host_ip()是直接返还ip地址的,所以在server的value部分我们直接使用get_host_ip()即可。

读取基础配置信息

在开屏弹窗中我们需要显示基本信息,所以我们先需要读取json文件内的我们需要的value值,代码如下:

#读取json 获取端口/密码/加密方式

filename = 'config.json'
with open(filename, 'r') as f:
    data = json.load(f)
    a = data['password']
    b = data['server_port']
    c = data['method']

弹窗

弹窗使用的是tkinter库,语法也十分简单,代码如下:

def talk():
    tkinter.messagebox.showinfo("提示","你的ip地址是" + get_host_ip()+"\n你的端口号是"+str(b)+"\n你的密码是" + a + "\n加密方式是"+ c +"\n请勿关闭cmd窗口")

实现界面如图

主程序

基本的小组件都写好了我们最后就把积木拼成小车车🚗就可以了,加入检测是否运行成功的弹窗,代码如下:

#主程序
netopen = threading.Thread(target=runserver)#, daemon=True)

if __name__=='__main__':
    netopen.start()
    if netopen.is_alive() == True:
        #弹窗显示
        talk()
        tkinter.messagebox.showinfo("欢迎","开启成功,如需退出请关闭cmd窗口")
    if  netopen.is_alive() == False:
        tkinter.messagebox.showinfo("退出","服务已退出,请检查配置")

大功告成

完整源码如下

import json
import os
import socket
import tkinter
import tkinter.messagebox
from threading import Thread
import threading

#初始化弹窗
root = tkinter.Tk()
root.withdraw()
root.wm_attributes('-topmost',1)

#获取实时IP地址
def get_host_ip():
    """
    查询本机ip地址
    :return: ip
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip

#将IP地址写入json文件

filename = 'config.json'
with open(filename, 'r') as f:
    data = json.load(f)
    data['server'] = get_host_ip() # <--- 添加实时ip地址.

os.remove(filename)
with open(filename, 'w') as f:
    json.dump(data, f, indent=4)


#读取json 获取端口/密码/加密方式

filename = 'config.json'
with open(filename, 'r') as f:
    data = json.load(f)
    a = data['password']
    b = data['server_port']
    c = data['method']

def runserver():
    os.system('shadowsocks-server.bat')
def talk():
    tkinter.messagebox.showinfo("提示","你的ip地址是" + get_host_ip()+"\n你的端口号是"+str(b)+"\n你的密码是" + a + "\n加密方式是"+ c +"\n请勿关闭cmd窗口")


#主程序
netopen = threading.Thread(target=runserver)#, daemon=True)

if __name__=='__main__':
    netopen.start()
    if netopen.is_alive() == True:
        #弹窗显示
        talk()
        tkinter.messagebox.showinfo("欢迎","开启成功,如需退出请关闭cmd窗口")
    if  netopen.is_alive() == False:
        tkinter.messagebox.showinfo("退出","服务已退出,请检查配置")

逻辑还是比较简单的,基本就是在调用不同的组件,但是成品还是很不错的,大大降低了学习和使用成本。

最后想说的话

这个方法对于校园网来说只能算是另辟蹊径,并没有完全从根本上解决问题,如果天翼校园的客户端能写得好一点,连接设备数能放宽一点,想必会受到更多学生的接纳。See you next time!欢迎评论!