server side message for network blocks
This commit is contained in:
parent
30c8aaeb91
commit
e3613b78ac
|
|
@ -0,0 +1,10 @@
|
|||
95.141.32.101/32
|
||||
93.115.28.181/32
|
||||
185.136.159.181/32
|
||||
79.141.162.81/32
|
||||
5.149.253.57/32
|
||||
5.149.255.178/32
|
||||
5.149.250.222/32
|
||||
77.83.198.123/32
|
||||
185.235.137.143/32
|
||||
83.143.87.194/32
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
173.245.48.0/20
|
||||
103.21.244.0/22
|
||||
103.22.200.0/22
|
||||
103.31.4.0/22
|
||||
141.101.64.0/18
|
||||
108.162.192.0/18
|
||||
190.93.240.0/20
|
||||
188.114.96.0/20
|
||||
197.234.240.0/22
|
||||
198.41.128.0/17
|
||||
162.158.0.0/15
|
||||
104.16.0.0/13
|
||||
104.24.0.0/14
|
||||
172.64.0.0/13
|
||||
131.0.72.0/22
|
||||
2400:cb00::/32
|
||||
2606:4700::/32
|
||||
2803:f800::/32
|
||||
2405:b500::/32
|
||||
2405:8100::/32
|
||||
2a06:98c0::/29
|
||||
2c0f:f248::/32
|
||||
|
|
@ -0,0 +1,488 @@
|
|||
14.102.63.0/24
|
||||
158.173.129.0/24
|
||||
158.173.130.0/24
|
||||
158.173.50.0/24
|
||||
146.19.7.0/25
|
||||
146.19.7.128/25
|
||||
62.169.132.0/24
|
||||
14.102.85.0/24
|
||||
2a0f:e385::/32
|
||||
14.102.52.0/24
|
||||
155.2.180.0/24
|
||||
155.2.181.0/24
|
||||
158.173.20.0/24
|
||||
158.173.21.0/24
|
||||
158.173.3.0/24
|
||||
188.213.203.0/24
|
||||
203.188.164.0/24
|
||||
212.56.48.0/24
|
||||
45.128.199.0/24
|
||||
92.51.255.0/24
|
||||
2a0e:4201::/32
|
||||
158.173.42.0/24
|
||||
158.173.43.0/24
|
||||
158.173.22.0/24
|
||||
193.56.116.0/24
|
||||
203.188.165.0/24
|
||||
212.32.49.0/24
|
||||
45.146.55.0/24
|
||||
185.184.134.0/24
|
||||
2a10:5a81::/32
|
||||
2a11:f885::/32
|
||||
2a11:f886::/32
|
||||
2a11:f887::/32
|
||||
14.102.53.0/24
|
||||
185.64.78.0/25
|
||||
185.64.78.128/25
|
||||
103.213.214.0/24
|
||||
103.61.198.0/24
|
||||
157.97.122.0/24
|
||||
185.114.34.0/24
|
||||
198.55.29.0/24
|
||||
2a0e:4203::/32
|
||||
155.2.217.0/24
|
||||
170.62.235.0/24
|
||||
170.62.244.0/24
|
||||
170.62.245.0/24
|
||||
170.62.237.0/24
|
||||
66.56.86.0/24
|
||||
158.173.36.0/24
|
||||
62.169.134.0/24
|
||||
157.97.120.0/24
|
||||
158.173.49.0/24
|
||||
170.62.246.0/24
|
||||
198.55.30.0/24
|
||||
2a0b:64c3::/32
|
||||
14.102.61.0/24
|
||||
193.218.32.0/24
|
||||
2.57.170.0/24
|
||||
37.46.149.0/24
|
||||
45.134.22.0/24
|
||||
89.251.2.0/24
|
||||
92.51.253.0/24
|
||||
103.125.78.0/24
|
||||
103.125.79.0/24
|
||||
103.210.198.0/24
|
||||
103.210.199.0/24
|
||||
185.239.243.0/24
|
||||
185.34.108.0/24
|
||||
185.34.109.0/24
|
||||
185.34.110.0/24
|
||||
185.34.111.0/24
|
||||
212.119.34.0/24
|
||||
45.135.184.0/24
|
||||
84.51.234.0/24
|
||||
84.51.235.0/24
|
||||
45.129.133.0/24
|
||||
89.46.92.0/25
|
||||
89.46.92.128/25
|
||||
103.210.197.0/24
|
||||
167.160.12.0/24
|
||||
178.239.204.0/24
|
||||
185.228.225.0/24
|
||||
45.86.203.0/24
|
||||
84.51.233.0/24
|
||||
14.102.54.0/24
|
||||
103.213.215.0/24
|
||||
155.2.212.0/24
|
||||
155.2.194.0/24
|
||||
155.2.195.0/24
|
||||
170.62.224.0/24
|
||||
185.192.16.0/24
|
||||
185.227.33.0/24
|
||||
92.51.252.0/24
|
||||
2a0b:64c5::/32
|
||||
158.173.6.0/24
|
||||
158.173.7.0/24
|
||||
136.144.43.0/24
|
||||
193.56.117.0/24
|
||||
203.188.175.0/24
|
||||
212.32.68.0/24
|
||||
212.32.69.0/24
|
||||
45.132.115.0/24
|
||||
2a0e:d787::/32
|
||||
170.62.239.0/24
|
||||
158.173.140.0/24
|
||||
158.173.141.0/24
|
||||
136.144.26.0/24
|
||||
155.2.176.0/24
|
||||
155.2.177.0/24
|
||||
158.173.154.0/24
|
||||
158.173.155.0/24
|
||||
158.173.156.0/24
|
||||
170.62.94.0/24
|
||||
203.188.181.0/24
|
||||
213.254.174.0/24
|
||||
45.130.143.0/24
|
||||
45.157.139.0/25
|
||||
45.157.139.128/25
|
||||
45.86.202.0/24
|
||||
45.91.148.0/25
|
||||
45.91.148.128/25
|
||||
91.217.249.0/24
|
||||
92.51.250.0/24
|
||||
124.198.144.0/24
|
||||
66.56.84.0/24
|
||||
212.32.75.0/24
|
||||
155.2.221.0/24
|
||||
155.2.222.0/24
|
||||
170.62.234.0/24
|
||||
193.176.211.0/24
|
||||
194.5.83.0/24
|
||||
92.51.248.0/24
|
||||
92.51.251.0/24
|
||||
2a0e:d781::/32
|
||||
103.255.77.0/24
|
||||
155.2.215.0/24
|
||||
167.160.16.0/24
|
||||
185.121.122.0/24
|
||||
185.244.137.0/24
|
||||
81.95.60.0/24
|
||||
81.95.61.0/24
|
||||
92.51.232.0/24
|
||||
92.51.233.0/24
|
||||
14.102.62.0/24
|
||||
2a0f:f43::/32
|
||||
14.102.84.0/24
|
||||
45.8.25.0/24
|
||||
45.93.164.0/24
|
||||
167.160.29.0/24
|
||||
212.78.248.0/24
|
||||
62.169.131.0/24
|
||||
81.95.58.0/24
|
||||
81.95.59.0/24
|
||||
14.102.87.0/24
|
||||
45.130.81.0/24
|
||||
107.150.166.0/24
|
||||
136.144.33.0/24
|
||||
158.173.54.0/24
|
||||
170.62.160.0/24
|
||||
192.140.220.0/24
|
||||
192.140.221.0/24
|
||||
193.36.225.0/24
|
||||
194.5.52.0/24
|
||||
212.56.53.0/24
|
||||
213.254.161.0/24
|
||||
213.254.175.0/24
|
||||
45.150.181.0/24
|
||||
45.150.182.0/24
|
||||
45.150.183.0/24
|
||||
45.159.246.0/24
|
||||
62.100.210.0/24
|
||||
92.51.234.0/24
|
||||
92.51.235.0/24
|
||||
2a0e:d785::/32
|
||||
2a11:53c2::/32
|
||||
2a11:53c3::/32
|
||||
2a11:53c4::/32
|
||||
2a11:53c5::/32
|
||||
158.173.4.0/24
|
||||
158.173.5.0/24
|
||||
185.245.5.0/24
|
||||
203.188.167.0/24
|
||||
212.78.246.0/24
|
||||
103.210.196.0/24
|
||||
158.173.23.0/24
|
||||
158.173.24.0/24
|
||||
170.62.229.0/24
|
||||
178.239.198.0/24
|
||||
185.161.111.0/24
|
||||
185.192.69.0/24
|
||||
185.192.70.0/24
|
||||
185.198.243.0/24
|
||||
185.217.117.0/24
|
||||
188.240.74.0/24
|
||||
193.218.35.0/24
|
||||
194.32.120.0/24
|
||||
203.188.182.0/24
|
||||
213.109.151.0/25
|
||||
213.109.151.128/25
|
||||
45.144.226.0/24
|
||||
45.85.127.0/24
|
||||
84.51.232.0/24
|
||||
85.203.34.0/24
|
||||
85.203.8.0/24
|
||||
2a07:bdc1::/32
|
||||
2a0e:d784::/32
|
||||
2a0e:d786::/32
|
||||
2a11:53c0::/32
|
||||
2a11:53c1::/32
|
||||
2a11:f881::/32
|
||||
2a11:f882::/32
|
||||
158.173.134.0/24
|
||||
158.173.135.0/24
|
||||
212.32.50.0/24
|
||||
45.130.141.0/24
|
||||
188.240.73.0/24
|
||||
212.56.49.0/24
|
||||
45.91.23.0/24
|
||||
212.32.72.0/24
|
||||
2a0f:f42::/32
|
||||
45.154.138.0/24
|
||||
170.62.238.0/24
|
||||
45.91.20.0/24
|
||||
2a07:e342::/32
|
||||
194.61.40.0/24
|
||||
194.61.41.0/24
|
||||
62.169.128.0/24
|
||||
217.119.143.0/25
|
||||
217.119.143.128/25
|
||||
130.255.168.0/25
|
||||
130.255.168.128/25
|
||||
155.2.182.0/24
|
||||
155.2.183.0/24
|
||||
170.62.225.0/24
|
||||
185.198.155.0/25
|
||||
185.198.155.128/25
|
||||
212.78.249.0/24
|
||||
89.38.70.0/25
|
||||
89.38.70.128/25
|
||||
2a0f:f40::/32
|
||||
2a11:53c6::/32
|
||||
2a11:53c7::/32
|
||||
2a11:f883::/32
|
||||
2a11:f884::/32
|
||||
103.125.76.0/24
|
||||
136.144.19.0/24
|
||||
158.173.59.0/24
|
||||
170.62.232.0/24
|
||||
185.121.120.0/24
|
||||
185.94.65.0/24
|
||||
185.94.66.0/24
|
||||
192.140.222.0/24
|
||||
192.140.223.0/24
|
||||
193.36.224.0/24
|
||||
45.132.113.0/24
|
||||
81.95.48.0/24
|
||||
81.95.49.0/24
|
||||
92.51.236.0/24
|
||||
92.51.237.0/24
|
||||
136.144.35.0/24
|
||||
185.198.240.0/25
|
||||
185.198.240.128/25
|
||||
192.253.209.0/24
|
||||
2.57.168.0/24
|
||||
212.56.54.0/24
|
||||
213.254.163.0/24
|
||||
14.102.86.0/24
|
||||
203.159.81.0/24
|
||||
103.255.76.0/24
|
||||
109.205.190.0/25
|
||||
109.205.190.128/25
|
||||
155.2.186.0/24
|
||||
155.2.187.0/24
|
||||
155.2.188.0/24
|
||||
158.173.25.0/24
|
||||
158.173.55.0/24
|
||||
170.62.102.0/24
|
||||
170.62.103.0/24
|
||||
170.62.106.0/24
|
||||
170.62.107.0/24
|
||||
170.62.108.0/24
|
||||
185.51.54.0/24
|
||||
192.253.208.0/24
|
||||
194.62.16.0/25
|
||||
194.62.16.128/25
|
||||
45.130.83.0/24
|
||||
45.157.99.0/24
|
||||
45.8.19.0/24
|
||||
45.85.124.0/24
|
||||
45.92.229.0/24
|
||||
81.95.62.0/24
|
||||
81.95.63.0/24
|
||||
89.43.199.0/25
|
||||
89.43.199.128/25
|
||||
92.51.238.0/24
|
||||
92.51.239.0/24
|
||||
93.115.254.0/24
|
||||
2a0f:e383::/32
|
||||
185.155.103.0/25
|
||||
185.155.103.128/25
|
||||
45.129.132.0/24
|
||||
203.25.124.0/25
|
||||
203.25.124.128/25
|
||||
212.32.76.0/24
|
||||
170.62.247.0/24
|
||||
212.78.244.0/24
|
||||
45.150.93.0/24
|
||||
45.92.228.0/24
|
||||
2a0b:64c2::/32
|
||||
170.62.228.0/24
|
||||
158.173.157.0/24
|
||||
158.173.158.0/24
|
||||
170.62.233.0/24
|
||||
170.62.92.0/24
|
||||
170.62.93.0/24
|
||||
178.211.136.0/25
|
||||
178.211.136.128/25
|
||||
194.5.53.0/24
|
||||
195.64.107.0/25
|
||||
195.64.107.128/25
|
||||
195.64.108.0/25
|
||||
195.64.108.128/25
|
||||
195.64.113.0/25
|
||||
195.64.113.128/25
|
||||
203.188.183.0/24
|
||||
45.140.135.0/24
|
||||
45.146.53.0/24
|
||||
45.157.112.0/24
|
||||
45.91.22.0/24
|
||||
81.95.50.0/24
|
||||
81.95.51.0/24
|
||||
92.51.249.0/24
|
||||
2a0f:e387::/32
|
||||
103.61.196.0/24
|
||||
146.19.29.0/25
|
||||
146.19.29.128/25
|
||||
167.160.28.0/24
|
||||
170.62.88.0/24
|
||||
185.245.7.0/24
|
||||
198.55.31.0/24
|
||||
212.32.73.0/24
|
||||
220.158.199.0/24
|
||||
45.133.5.0/24
|
||||
45.150.180.0/24
|
||||
45.67.96.0/24
|
||||
66.56.87.0/24
|
||||
2a0f:e384::/32
|
||||
158.173.18.0/24
|
||||
158.173.19.0/24
|
||||
170.62.236.0/24
|
||||
66.56.85.0/24
|
||||
14.102.60.0/24
|
||||
158.173.52.0/24
|
||||
158.173.53.0/24
|
||||
2a0e:4207::/32
|
||||
2a0e:4206::/32
|
||||
103.213.212.0/24
|
||||
155.2.184.0/24
|
||||
155.2.185.0/24
|
||||
158.173.45.0/24
|
||||
167.160.17.0/24
|
||||
170.62.231.0/24
|
||||
185.121.123.0/24
|
||||
185.239.241.0/24
|
||||
45.146.54.0/24
|
||||
93.185.160.0/24
|
||||
194.62.107.0/25
|
||||
194.62.107.128/25
|
||||
220.158.198.0/24
|
||||
89.36.23.0/24
|
||||
93.114.192.0/24
|
||||
213.254.160.0/24
|
||||
45.131.195.0/24
|
||||
14.102.55.0/24
|
||||
203.188.168.0/24
|
||||
2a0b:64c4::/32
|
||||
170.62.95.0/24
|
||||
185.150.0.0/24
|
||||
193.37.32.0/24
|
||||
194.5.82.0/24
|
||||
203.188.189.0/24
|
||||
203.188.190.0/24
|
||||
203.188.191.0/24
|
||||
212.78.247.0/24
|
||||
213.109.152.0/25
|
||||
213.109.152.128/25
|
||||
31.222.218.0/24
|
||||
31.222.219.0/24
|
||||
45.128.198.0/24
|
||||
85.203.23.0/24
|
||||
89.47.15.0/25
|
||||
89.47.15.128/25
|
||||
2a0e:4205::/32
|
||||
158.173.44.0/24
|
||||
170.62.226.0/24
|
||||
170.62.89.0/24
|
||||
212.78.250.0/24
|
||||
45.135.187.0/24
|
||||
45.157.98.0/24
|
||||
45.91.21.0/24
|
||||
2a0e:4204::/32
|
||||
185.92.24.0/24
|
||||
62.169.130.0/24
|
||||
2a0b:64c7::/32
|
||||
158.173.142.0/24
|
||||
158.173.143.0/24
|
||||
158.173.33.0/24
|
||||
158.173.34.0/24
|
||||
103.125.77.0/24
|
||||
103.213.213.0/24
|
||||
158.173.153.0/24
|
||||
158.173.32.0/24
|
||||
158.173.47.0/24
|
||||
185.121.121.0/24
|
||||
193.19.109.0/24
|
||||
193.37.33.0/24
|
||||
193.39.215.0/25
|
||||
193.39.215.128/25
|
||||
85.8.130.0/25
|
||||
85.8.130.128/25
|
||||
203.188.169.0/24
|
||||
2a0b:64c6::/32
|
||||
103.61.199.0/24
|
||||
136.144.17.0/24
|
||||
170.62.110.0/24
|
||||
170.62.111.0/24
|
||||
185.205.190.0/24
|
||||
185.92.26.0/24
|
||||
198.55.28.0/24
|
||||
2.57.169.0/24
|
||||
212.32.48.0/24
|
||||
31.222.216.0/24
|
||||
31.222.217.0/24
|
||||
45.130.80.0/24
|
||||
62.169.129.0/24
|
||||
66.56.80.0/24
|
||||
66.56.81.0/24
|
||||
66.56.82.0/24
|
||||
89.251.0.0/24
|
||||
93.115.255.0/24
|
||||
2a0f:e386::/32
|
||||
45.86.200.0/24
|
||||
85.203.13.0/24
|
||||
155.2.178.0/24
|
||||
155.2.179.0/24
|
||||
155.2.216.0/24
|
||||
170.62.91.0/24
|
||||
188.212.132.0/24
|
||||
194.5.48.0/24
|
||||
203.188.170.0/24
|
||||
89.36.22.0/24
|
||||
89.37.62.0/24
|
||||
92.51.254.0/24
|
||||
93.185.161.0/24
|
||||
2a0e:4202::/32
|
||||
158.173.16.0/24
|
||||
158.173.17.0/24
|
||||
192.253.210.0/24
|
||||
188.213.202.0/24
|
||||
194.5.49.0/24
|
||||
212.32.71.0/24
|
||||
103.61.197.0/24
|
||||
158.173.48.0/24
|
||||
185.192.68.0/24
|
||||
203.188.172.0/24
|
||||
45.144.129.0/24
|
||||
45.148.25.0/24
|
||||
45.95.243.0/24
|
||||
2a0e:d783::/32
|
||||
212.56.52.0/24
|
||||
62.169.135.0/24
|
||||
136.144.42.0/24
|
||||
136.144.27.0/24
|
||||
170.62.230.0/24
|
||||
188.212.135.0/25
|
||||
188.212.135.128/25
|
||||
212.78.245.0/24
|
||||
2a0e:d782::/32
|
||||
170.62.227.0/24
|
||||
158.173.152.0/24
|
||||
170.62.90.0/24
|
||||
188.240.68.0/25
|
||||
188.240.68.128/25
|
||||
212.56.50.0/24
|
||||
212.78.251.0/24
|
||||
81.95.56.0/24
|
||||
81.95.57.0/24
|
||||
2a0f:f41::/32
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { Elysia } from 'elysia';
|
||||
import { m, eta, error } from '@/utils/html'
|
||||
import healthStatus from '@/utils/health';
|
||||
import { checkIpRanges } from '@/utils/ranges';
|
||||
const app = new Elysia()
|
||||
|
||||
app.get('/', async ({ set }) => {
|
||||
|
|
@ -12,9 +13,17 @@ app.get('/', async ({ set }) => {
|
|||
}))
|
||||
})
|
||||
|
||||
app.get('/save', async ({ query: { url }, set, error }) => {
|
||||
app.get('/save', async ({ query: { url }, set, headers, error }) => {
|
||||
if (!url) return error(400, 'No url provided.')
|
||||
|
||||
const ranges = await checkIpRanges(headers['cf-connecting-ip'] || headers['x-forwarded-for'] || '')
|
||||
if (ranges.blocked) {
|
||||
set.headers['Content-Type'] = 'text/html; charset=utf-8'
|
||||
return await m(eta.render('./blocked', {
|
||||
title: 'Blocked | PreserveTube'
|
||||
}))
|
||||
}
|
||||
|
||||
let websocket = process.env.WEBSOCKET
|
||||
if (healthStatus[process.env.METADATA!] != 'healthy') {
|
||||
websocket = process.env.ALTERNATIVE_WEBSOCKET!
|
||||
|
|
@ -29,9 +38,17 @@ app.get('/save', async ({ query: { url }, set, error }) => {
|
|||
}))
|
||||
})
|
||||
|
||||
app.get('/savechannel', async ({ query: { url }, set, error }) => {
|
||||
app.get('/savechannel', async ({ query: { url }, set, headers, error }) => {
|
||||
if (!url) return error(400, 'No url provided.')
|
||||
|
||||
const ranges = await checkIpRanges(headers['cf-connecting-ip'] || headers['x-forwarded-for'] || '')
|
||||
if (ranges.blocked) {
|
||||
set.headers['Content-Type'] = 'text/html; charset=utf-8'
|
||||
return await m(eta.render('./blocked', {
|
||||
title: 'Blocked | PreserveTube'
|
||||
}))
|
||||
}
|
||||
|
||||
let websocket = process.env.WEBSOCKET
|
||||
if (healthStatus[process.env.METADATA!] != 'healthy') {
|
||||
websocket = process.env.ALTERNATIVE_WEBSOCKET!
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { getChannelVideos, getVideo } from '@/utils/metadata';
|
|||
import { error } from '@/utils/html'
|
||||
import redis from '@/utils/redis';
|
||||
import { parseSlop } from '@/utils/slop';
|
||||
import { checkIpRanges } from '@/utils/ranges';
|
||||
|
||||
const app = new Elysia()
|
||||
const videoIds: Record<string, string> = {}
|
||||
|
|
@ -92,6 +93,12 @@ app.ws('/save', {
|
|||
}),
|
||||
body: t.String(),
|
||||
open: async (ws) => {
|
||||
const range = await checkIpRanges(ws.data.headers['x-forwarded-for'] || '')
|
||||
if (range.list != 'cloudflare') return sendError(ws, 'There\'s something wrong with your connection.')
|
||||
|
||||
const blacklistCheck = await checkIpRanges(ws.data.headers['cf-connecting-ip']!)
|
||||
if (blacklistCheck.blocked) return sendError(ws, `Your network is flagged as malicious.`)
|
||||
|
||||
console.log(`${ws.id} - ${ws.data.path} - ${JSON.stringify(ws.data.query)}`)
|
||||
|
||||
const videoId = validateVideo(ws.data.query.url)
|
||||
|
|
@ -190,6 +197,12 @@ app.ws('/savechannel', {
|
|||
}),
|
||||
body: t.String(),
|
||||
open: async (ws) => {
|
||||
const range = await checkIpRanges(ws.data.headers['x-forwarded-for'] || '')
|
||||
if (range.list != 'cloudflare') return sendError(ws, 'There\'s something wrong with your connection.')
|
||||
|
||||
const blacklistCheck = await checkIpRanges(ws.data.headers['cf-connecting-ip']!)
|
||||
if (blacklistCheck.blocked) return sendError(ws, `Your network is flagged as malicious.`)
|
||||
|
||||
console.log(`${ws.id} - ${ws.data.path} - ${JSON.stringify(ws.data.query)}`)
|
||||
|
||||
const channelId = await validateChannel(ws.data.query.url);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
<% layout('./layout') %>
|
||||
|
||||
<div class="text">
|
||||
<p>
|
||||
We detected malicious activity from the network you are currently visiting from, so we have
|
||||
blocked certain functionality for this connection.
|
||||
</p>
|
||||
<p>
|
||||
This is most commonly caused by free VPNs, shared VPN exit nodes, or other heavily abused
|
||||
proxy networks.
|
||||
</p>
|
||||
<p>
|
||||
If you believe this is a mistake, please contact
|
||||
<a href="mailto:admin@preservetube.com">admin@preservetube.com</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.a {
|
||||
text-decoration-line: underline;
|
||||
text-decoration-style: dotted;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-top: 2.5%;
|
||||
margin-bottom: 5%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 75%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
import { readdir, readFile } from 'node:fs/promises'
|
||||
import * as path from 'node:path'
|
||||
|
||||
export interface BlockedIpResult {
|
||||
blocked: boolean
|
||||
list: string | null
|
||||
range: string | null
|
||||
}
|
||||
|
||||
const IPV6_BITS = 128n
|
||||
const IPV6_FULL_MASK = (1n << IPV6_BITS) - 1n
|
||||
const toBlockLists = ['expressvpn', '1clickvpn']
|
||||
|
||||
type ParsedIp =
|
||||
| { version: 4; value: number }
|
||||
| { version: 6; value: bigint }
|
||||
|
||||
type ParsedCidr =
|
||||
| { version: 4; network: number; mask: number }
|
||||
| { version: 6; network: bigint; mask: bigint }
|
||||
|
||||
function ipv4ToInt(ip: string): number | null {
|
||||
const parts = ip.trim().split('.')
|
||||
if (parts.length !== 4) return null
|
||||
|
||||
let result = 0
|
||||
for (const part of parts) {
|
||||
if (!/^\d+$/.test(part)) return null
|
||||
const value = Number(part)
|
||||
if (value < 0 || value > 255) return null
|
||||
result = (result << 8) + value
|
||||
}
|
||||
|
||||
return result >>> 0
|
||||
}
|
||||
|
||||
function parseIpv6(ip: string): bigint | null {
|
||||
let input = ip.trim().toLowerCase()
|
||||
if (!input) return null
|
||||
|
||||
const zoneSeparator = input.indexOf('%')
|
||||
if (zoneSeparator >= 0) {
|
||||
input = input.slice(0, zoneSeparator)
|
||||
}
|
||||
|
||||
if (input.includes('.')) {
|
||||
const lastColon = input.lastIndexOf(':')
|
||||
if (lastColon === -1) return null
|
||||
|
||||
const ipv4Part = input.slice(lastColon + 1)
|
||||
const ipv4Int = ipv4ToInt(ipv4Part)
|
||||
if (ipv4Int === null) return null
|
||||
|
||||
const high = ((ipv4Int >>> 16) & 0xffff).toString(16)
|
||||
const low = (ipv4Int & 0xffff).toString(16)
|
||||
input = `${input.slice(0, lastColon)}:${high}:${low}`
|
||||
}
|
||||
|
||||
if (input.split('::').length > 2) return null
|
||||
|
||||
const hasCompression = input.includes('::')
|
||||
const [leftPart, rightPart = ''] = input.split('::')
|
||||
const left = leftPart ? leftPart.split(':').filter(Boolean) : []
|
||||
const right = rightPart ? rightPart.split(':').filter(Boolean) : []
|
||||
|
||||
const isValidHextet = (value: string) => /^[0-9a-f]{1,4}$/.test(value)
|
||||
if (!left.every(isValidHextet) || !right.every(isValidHextet)) return null
|
||||
|
||||
if (hasCompression) {
|
||||
if (left.length + right.length > 7) return null
|
||||
} else if (left.length !== 8) {
|
||||
return null
|
||||
}
|
||||
|
||||
const missingCount = hasCompression ? 8 - (left.length + right.length) : 0
|
||||
const groups = [...left, ...Array(Math.max(0, missingCount)).fill('0'), ...right]
|
||||
if (groups.length !== 8) return null
|
||||
|
||||
let result = 0n
|
||||
for (const group of groups) {
|
||||
result = (result << 16n) + BigInt(parseInt(group, 16))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function parseIp(input: string): ParsedIp | null {
|
||||
const ipv4 = ipv4ToInt(input)
|
||||
if (ipv4 !== null) return { version: 4, value: ipv4 }
|
||||
|
||||
const ipv6 = parseIpv6(input)
|
||||
if (ipv6 !== null) return { version: 6, value: ipv6 }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function parseCidr(cidr: string): ParsedCidr | null {
|
||||
const [baseIp, prefixText] = cidr.split('/')
|
||||
if (!baseIp || !prefixText || !/^\d+$/.test(prefixText)) return null
|
||||
|
||||
const prefix = Number(prefixText)
|
||||
|
||||
const ip = parseIp(baseIp)
|
||||
if (!ip) return null
|
||||
|
||||
if (ip.version === 4) {
|
||||
if (prefix < 0 || prefix > 32) return null
|
||||
const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0
|
||||
return { version: 4, network: ip.value & mask, mask }
|
||||
}
|
||||
|
||||
if (prefix < 0 || prefix > 128) return null
|
||||
const mask =
|
||||
prefix === 0
|
||||
? 0n
|
||||
: (IPV6_FULL_MASK ^ ((1n << (IPV6_BITS - BigInt(prefix))) - 1n)) & IPV6_FULL_MASK
|
||||
|
||||
return { version: 6, network: ip.value & mask, mask }
|
||||
}
|
||||
|
||||
function isIpInCidr(ip: ParsedIp, cidr: string): boolean {
|
||||
const parsed = parseCidr(cidr)
|
||||
if (!parsed) return false
|
||||
|
||||
if (ip.version === 4 && parsed.version === 4) {
|
||||
return (ip.value & parsed.mask) === parsed.network
|
||||
}
|
||||
|
||||
if (ip.version === 6 && parsed.version === 6) {
|
||||
return (ip.value & parsed.mask) === parsed.network
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function extractCidrs(text: string): string[] {
|
||||
const cidrs: string[] = []
|
||||
const lines = text.split('\n')
|
||||
|
||||
for (const line of lines) {
|
||||
const cleaned = line.split('#')[0]?.trim()
|
||||
if (!cleaned) continue
|
||||
|
||||
const tokens = cleaned.split(/\s+/)
|
||||
for (const token of tokens) {
|
||||
if (!token.includes('/')) continue
|
||||
cidrs.push(token.replace(/^[,;]+|[,;]+$/g, ''))
|
||||
}
|
||||
}
|
||||
|
||||
return cidrs
|
||||
}
|
||||
|
||||
export async function checkIpRanges(ip: string): Promise<BlockedIpResult> {
|
||||
const parsedIp = parseIp(ip)
|
||||
if (parsedIp == null) {
|
||||
return { blocked: false, list: null, range: null }
|
||||
}
|
||||
|
||||
const blockedDir = path.resolve(process.cwd(), 'ranges')
|
||||
const entries = await readdir(blockedDir, { withFileTypes: true })
|
||||
|
||||
const files = entries
|
||||
.filter(entry => entry.isFile() && entry.name.endsWith('.txt'))
|
||||
.map(entry => entry.name)
|
||||
.sort((a, b) => a.localeCompare(b))
|
||||
|
||||
for (const fileName of files) {
|
||||
const filePath = path.join(blockedDir, fileName)
|
||||
const content = await readFile(filePath, 'utf8')
|
||||
const cidrs = extractCidrs(content)
|
||||
|
||||
for (const cidr of cidrs) {
|
||||
if (isIpInCidr(parsedIp, cidr)) {
|
||||
return {
|
||||
blocked: toBlockLists.includes(path.basename(fileName, '.txt')),
|
||||
list: path.basename(fileName, '.txt'),
|
||||
range: cidr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { blocked: false, list: null, range: null }
|
||||
}
|
||||
Loading…
Reference in New Issue