Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

改进&升级了一下配置中心中的统计页和客户端管理列表页. #189

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
efbd5b6
Contributed some knowledge about the jsk generation and configuration.
Haoke98 Dec 1, 2022
acc1458
增加了下一步目标
Haoke98 Dec 2, 2022
f3527a8
更新了README, 增加了如何在IDEA上进行运行和调试的开发步骤教程
Haoke98 Apr 20, 2023
3584c44
初步实现了对客户端管理模块的列表页面进行修改(增加了映射数量)
Haoke98 Mar 13, 2024
76744c9
初步实现了对数据统计页的修改(增加了流入消息和流出消息数量)
Haoke98 Mar 13, 2024
e114459
重新用最新版Layui.js中的table组件是吸纳了数据统计页面的统计结果表格,实现了表格数据的实时异步更新,增加了流入消息数量和流出消…
Haoke98 Mar 13, 2024
7fec6f3
更新了统计页面预览图
Haoke98 Mar 14, 2024
5e9a352
调整了版本号,增加了一些关键TODO
Haoke98 Mar 20, 2024
28f23fe
初步实现了针对ProxyMessage和Channel创建的记录进行记录并在网页上展示
Haoke98 Nov 11, 2024
be5f6ae
改成对服务端公网端口收到的请求进行监控并记录
Haoke98 Nov 11, 2024
2f07187
初步实现了对TCP/UDP请求包的简单解析(目前只针对http/https请求做简单解析,解析出请求类型,协议头)并网页上展示.
Haoke98 Nov 11, 2024
c0cd9a1
进一步优化了TCP/UDP请求包的解析
Haoke98 Nov 11, 2024
2cef711
进一步优化了TCP/UDP请求包的解析,增加了PostgreSQL自定义的TCP请求包的解析和DNS的TCP请求包的解析
Haoke98 Nov 11, 2024
5ccb3c8
进一步优化了TCP/UDP请求包的解析,增加了对SSH协议的支持
Haoke98 Nov 11, 2024
b40ffbe
优化了展示效果,使表格铺满整个屏幕
Haoke98 Nov 11, 2024
fa42de9
在管理控制台里面另起菜单把“日志记录”展示页面移植进去了,采用了layui的模版引入形式.
Haoke98 Nov 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .cursorignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
.idea
distribution
*.zip
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@
.*
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
/test.sh
*/logs/
*/target/
*.zip
70 changes: 56 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

https://nat.nioee.com


## Lanproxy个人升级版

核心功能:
Expand All @@ -19,7 +18,7 @@ https://nat.nioee.com

体验地址 https://lanp.nioee.com (测试用户名密码 test/123456)

![panel](panel.png)
![panel](assets/panel.png)

## Lanproxy开源免费版

Expand All @@ -37,8 +36,8 @@ lanproxy是一个将局域网个人电脑、服务器代理到公网的内网穿

#### 获取发布包

- 拉取源码,运行 mvn package,打包后的资源放在distribution目录中,包括client和server
- 或直接下载发布包 https://github.com/ffay/lanproxy/releases
- 拉取源码,运行 mvn package,打包后的资源放在distribution目录中,包括client和server
- 或直接下载发布包 https://github.com/ffay/lanproxy/releases

#### 配置

Expand All @@ -48,21 +47,17 @@ server的配置文件放置在conf目录中,配置 config.properties

```properties
server.bind=0.0.0.0

#与代理客户端通信端口
server.port=4900

#ssl相关配置
server.ssl.enable=true
server.ssl.bind=0.0.0.0
server.ssl.port=4993
server.ssl.jksPath=test.jks
server.ssl.keyStorePassword=123456
server.ssl.keyManagerPassword=123456

#这个配置可以忽略
server.ssl.needsClientAuth=false

#WEB在线配置管理相关信息
config.server.bind=0.0.0.0
config.server.port=8090
Expand All @@ -72,11 +67,14 @@ config.admin.password=admin

代理配置,打开地址 http://ip:8090 ,使用上面配置中配置的用户名密码登录,进入如下代理配置界面

![webconfig](readme_zh_client_list.png)
![webconfig](assets/readme_zh_client_list.png)

![webconfig](readme_zh_proxy_list.png)
![webconfig](assets/readme_zh_proxy_list.png)

![webconfig](readme_zh_stat_list.png)
![webconfig](assets/readme_zh_stat_list.png)

TCP请求包内容记录并在网页上展示:
![RequestLogShow](assets/RequestLog.png)

> 一个server可以支持多个客户端连接
> 配置数据存放在 ~/.lanproxy/config.json 文件中
Expand All @@ -92,10 +90,8 @@ client.key=
ssl.enable=true
ssl.jksPath=test.jks
ssl.keyStorePassword=123456

#这里填写实际的proxy-server地址;没有服务器默认即可,自己有服务器的更换为自己的proxy-server(IP)地址
server.host=lp.thingsglobal.org

#proxy-server ssl默认端口4993,默认普通端口4900
#ssl.enable=true时这里填写ssl端口,ssl.enable=false时这里填写普通端口
server.port=4993
Expand Down Expand Up @@ -145,5 +141,51 @@ nohup ./client_linux_amd64 -s SERVER_IP -p SERVER_SSL_PORT -k CLIENT_KEY -ssl tr

#### 其他

- 在家里使用公司的网络,可以和 https://github.com/ffay/http-proxy-server 这个http代理项目配合使用(个人升级版已经内置代理上网功能,详细资料 https://file.nioee.com/f/76ebbce67c864e4dbe7e/ )
- 在家里使用公司的网络,可以和 https://github.com/ffay/http-proxy-server
这个http代理项目配合使用(个人升级版已经内置代理上网功能,详细资料 https://file.nioee.com/f/76ebbce67c864e4dbe7e/ )
- 对于正常网站,80和443端口只有一个,可以购买个人升级版本解决端口复用问题

## 生成 JSK 文件

```shell
keytool -genkey -keyalg RSA -keysize 2048 -validity 365 -dname "CN=test, OU=test,O=test, L=shanghai, ST=shanghai, C=CN" -alias csii_key -keypass 888888 -keystore sdm-202212011626.jks -storepass 123456
```

### ⚠️注️:

> 1. 当-keypass 和 -storepass 设为不同时,keytool会给出以下警告:
> ```shell
> 警告: PKCS12 密钥库不支持其他存储和密钥口令。正在忽略用户指定的-keypass值。
> ```
> 这时在configuration.properties文件中keyStore和keyManager密码必须为一直是kesStore的密码。
> ```properties
> server.ssl.keyStorePassword=123456(keystore密码)
> server.ssl.keyManagerPassword=123456(keystore密码)
> ```
> 2.提高安全性: keysize必须为大于等于2048
> ```shell
> 生成的证书 使用的 1024 位 RSA 密钥 被视为存在安全风险。此密钥大小将在未来的更新中被禁用。
>```
> 详情请见 [“陷阱”素数(‘trapdoored’ primes)的出现,使用1024位密钥加密算法已不再安全](https://searchsecurity.techtarget.com.cn/11-24358/)

### 进阶版

#### 映射配置

![webconfig](assets/进阶版配置表单截图.png)

### 开发&调试

如果想在IDEA中运行并调试,务必要配置Application Configuration
![img.png](assets/application-configuration-shortcut.png)
JVM Options:
```shell
-Dapp.home=<项目的绝对路径>/proxy-server
-Djava.awt.headless=true
-Djava.net.preferIPv4Stack=true
-Djdk.tls.rejectClientInitiatedRenegotiation=true
-Xdebug
-Xnoagent
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,address=12000,server=y,suspend=n
```
8 changes: 4 additions & 4 deletions README_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Lanproxy is a reverse proxy to help you expose a local server behind a NAT or fi
- Run personal cloud services from your own private network

### Architecture
![lanproxy](lanproxy.png)
![lanproxy](assets/lanproxy.png)

### Configure

Expand Down Expand Up @@ -52,11 +52,11 @@ config.admin.password=admin

> Visit your config web service using url http://ip:8090

![webconfig](readme_en_client_list.png)
![webconfig](assets/readme_en_client_list.png)

![webconfig](readme_en_proxy_list.png)
![webconfig](assets/readme_en_proxy_list.png)

![webconfig](readme_en_stat_list.png)
![webconfig](assets/readme_en_stat_list.png)

#### client

Expand Down
Binary file added assets/RequestLog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/application-configuration-shortcut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Binary file added assets/readme_zh_stat_list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/进阶版配置表单截图.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions lanproxy.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/distribution" />
</content>
</component>
</module>
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
Expand Down Expand Up @@ -49,8 +51,6 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelOption;
import io.netty.util.AttributeKey;

/**
Expand Down
4 changes: 2 additions & 2 deletions proxy-client/src/main/resources/config.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
client.key=client
client.key=7815c64fbd02420c84c347704a8967b5
ssl.enable=false
ssl.jksPath=test.jks
ssl.keyStorePassword=123456

server.host=127.0.0.1
server.host=192.168.31.115

#default ssl port is 4993
server.port=4900
1 change: 1 addition & 0 deletions proxy-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<artifactId>proxy-server</artifactId>
<packaging>jar</packaging>
<name>proxy-server</name>
<version>${parent.version}.1</version>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
Expand Down
8 changes: 8 additions & 0 deletions proxy-server/proxy-server.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<excludeFolder url="file://$MODULE_DIR$/logs" />
</content>
</component>
</module>
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ private void startUserPort() {

@Override
public void initChannel(SocketChannel ch) throws Exception {
// // TODO: 这里实现一个流量和访问日志的记录
logger.info("{}===>{}", ch.remoteAddress(), ch.localAddress());
ch.pipeline().addFirst(new BytesMetricsHandler());
ch.pipeline().addLast(new UserChannelHandler());
}
Expand Down Expand Up @@ -171,7 +173,7 @@ private ChannelHandler createSslHandler(SSLContext sslContext, boolean needsClie
}

public static void main(String[] args) {
ContainerHelper.start(Arrays.asList(new Container[] { new ProxyServerContainer(), new WebConfigContainer() }));
ContainerHelper.start(Arrays.asList(new Container[]{new ProxyServerContainer(), new WebConfigContainer()}));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.fengfei.lanproxy.server.config.web.ResponseInfo;
import org.fengfei.lanproxy.server.config.web.exception.ContextException;
import org.fengfei.lanproxy.server.metrics.MetricsCollector;
import org.fengfei.lanproxy.server.requestlogs.RequestLogCollector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -170,6 +171,14 @@ public ResponseInfo request(FullHttpRequest request) {
return ResponseInfo.build(MetricsCollector.getAndResetAllMetrics());
}
});
// 添加获取日志的路由
ApiRoute.addRoute("/api/logs", new RequestHandler() {

@Override
public ResponseInfo request(FullHttpRequest request) {
return ResponseInfo.build(ResponseInfo.CODE_OK, "success", RequestLogCollector.getRecentLogs());
}
});
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.fengfei.lanproxy.server.handlers;

import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class RequestInterceptor {

private static final int MAX_REQUESTS_PER_SECOND = 100; // 每秒最大请求数
private static final int BLACK_LIST_THRESHOLD = 1000; // 加入黑名单阈值
private static final Logger logger = LoggerFactory.getLogger(RequestInterceptor.class);

// 使用ConcurrentHashMap存储IP访问统计
private final ConcurrentHashMap<String, AccessStats> statsMap = new ConcurrentHashMap<>();

// IP黑名单
private final Set<String> blackList = ConcurrentHashMap.newKeySet();

public boolean interceptRequest(Channel channel) {
InetSocketAddress address = (InetSocketAddress) channel.remoteAddress();
String ip = address.getAddress().getHostAddress();

// 检查是否在黑名单中
if (blackList.contains(ip)) {
logger.warn("Blocked request from blacklisted IP: {}", ip);
return true;
}

// 获取或创建访问统计
AccessStats stats = statsMap.computeIfAbsent(ip, k -> new AccessStats());

// 检查频率限制
if (stats.isExceedingLimit()) {
stats.incrementBlockCount();

// 超过阈值加入黑名单
if (stats.getBlockCount() > BLACK_LIST_THRESHOLD) {
blackList.add(ip);
logger.warn("Added IP to blacklist: {}", ip);
}

return true;
}

// 记录请求
stats.recordRequest();
return false;
}

private static class AccessStats {
private AtomicInteger requestCount = new AtomicInteger(0);
private AtomicInteger blockCount = new AtomicInteger(0);
private long lastResetTime = System.currentTimeMillis();

public boolean isExceedingLimit() {
resetIfNeeded();
return requestCount.get() >= MAX_REQUESTS_PER_SECOND;
}

public void recordRequest() {
resetIfNeeded();
requestCount.incrementAndGet();
}

public void incrementBlockCount() {
blockCount.incrementAndGet();
}

public int getBlockCount() {
return blockCount.get();
}

private void resetIfNeeded() {
long now = System.currentTimeMillis();
if (now - lastResetTime > 1000) {
requestCount.set(0);
lastResetTime = now;
}
}
}
}
Loading