mirror of
https://github.com/itdoginfo/allow-domains.git
synced 2026-01-25 10:07:14 +03:00
Compare commits
23 Commits
2025-02-08
...
2025-02-11
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0667ea32ca | ||
|
|
7289dfaa46 | ||
|
|
117632f692 | ||
|
|
793bb265ae | ||
|
|
94a5d8fccd | ||
|
|
b75eb3aaec | ||
|
|
bdfb0cf815 | ||
|
|
0170df9089 | ||
|
|
493dab4a54 | ||
|
|
9b99ebbd6b | ||
|
|
52a521e9ff | ||
|
|
ca9854a92b | ||
|
|
238ff0532e | ||
|
|
024b2975f3 | ||
|
|
679b1bc98d | ||
|
|
65fab2c74f | ||
|
|
cb359ccbb3 | ||
|
|
6c4605722e | ||
|
|
84490104be | ||
|
|
ccb8b42a43 | ||
|
|
4ab1ff94dc | ||
|
|
b6ae5b3761 | ||
|
|
b1def56e61 |
8
.github/workflows/create-lists.yml
vendored
8
.github/workflows/create-lists.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
-v ${{ github.workspace }}/Services:/app/Services \
|
||||
-v ${{ github.workspace }}/SRS:/app/SRS \
|
||||
-v ${{ github.workspace }}/DAT:/app/DAT \
|
||||
itdoginfo/compilesrs:0.1.5
|
||||
itdoginfo/compilesrs:0.1.10
|
||||
|
||||
- name: Check Russia/inside-dnsmasq-ipset
|
||||
uses: itdoginfo/dnsmasq-action@0.1
|
||||
@@ -80,6 +80,6 @@ jobs:
|
||||
uses: softprops/action-gh-release@v2.1.0
|
||||
with:
|
||||
files: |
|
||||
"${{ github.workspace }}/SRS/*.srs"
|
||||
"${{ github.workspace }}/DAT/*.dat"
|
||||
tag_name: ${{ env.TAG_NAME }}
|
||||
${{ github.workspace }}/SRS/*.srs
|
||||
${{ github.workspace }}/DAT/*.dat
|
||||
tag_name: ${{ env.TAG_NAME }}
|
||||
|
||||
@@ -234,4 +234,5 @@ medium.com
|
||||
navalny.com
|
||||
nih.gov
|
||||
omv-extras.org
|
||||
seasonvar.ru
|
||||
seasonvar.ru
|
||||
bestchange.ru
|
||||
@@ -258,4 +258,5 @@ cisco.com
|
||||
fluke.com
|
||||
iherb.com
|
||||
spotify.com
|
||||
weather.com
|
||||
weather.com
|
||||
typing.com
|
||||
@@ -35,6 +35,7 @@ kavkazr.com
|
||||
svoboda.org
|
||||
bbc.com
|
||||
bbc.co.uk
|
||||
bbci.co.uk
|
||||
freemedia.io
|
||||
dw.com
|
||||
idelreal.org
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
FROM ghcr.io/sagernet/sing-box:v1.10.7 AS sing-box
|
||||
FROM ghcr.io/sagernet/sing-box:v1.11.3 AS sing-box
|
||||
|
||||
FROM golang:1.22.12-alpine3.21 AS go-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN CGO_ENABLED=0 GOOS=linux go install -ldflags="-s -w" \
|
||||
github.com/v2fly/domain-list-community@20250207120917
|
||||
|
||||
|
||||
@@ -66,10 +66,12 @@ DOMAIN-SUFFIX,baikal-journal.ru
|
||||
DOMAIN-SUFFIX,bato.to
|
||||
DOMAIN-SUFFIX,bbc.co.uk
|
||||
DOMAIN-SUFFIX,bbc.com
|
||||
DOMAIN-SUFFIX,bbci.co.uk
|
||||
DOMAIN-SUFFIX,bcbits.com
|
||||
DOMAIN-SUFFIX,bell-sw.com
|
||||
DOMAIN-SUFFIX,bellingcat.com
|
||||
DOMAIN-SUFFIX,bestbuy.com
|
||||
DOMAIN-SUFFIX,bestchange.ru
|
||||
DOMAIN-SUFFIX,bihus.info
|
||||
DOMAIN-SUFFIX,bitdefender.com
|
||||
DOMAIN-SUFFIX,blackseanews.net
|
||||
@@ -700,6 +702,7 @@ DOMAIN-SUFFIX,twtrdns.net
|
||||
DOMAIN-SUFFIX,twttr.com
|
||||
DOMAIN-SUFFIX,twttr.net
|
||||
DOMAIN-SUFFIX,twvid.com
|
||||
DOMAIN-SUFFIX,typing.com
|
||||
DOMAIN-SUFFIX,ui.ill.in.ua
|
||||
DOMAIN-SUFFIX,ukr.net
|
||||
DOMAIN-SUFFIX,ukr.radio
|
||||
|
||||
@@ -66,10 +66,12 @@ ipset=/baikal-journal.ru/vpn_domains
|
||||
ipset=/bato.to/vpn_domains
|
||||
ipset=/bbc.co.uk/vpn_domains
|
||||
ipset=/bbc.com/vpn_domains
|
||||
ipset=/bbci.co.uk/vpn_domains
|
||||
ipset=/bcbits.com/vpn_domains
|
||||
ipset=/bell-sw.com/vpn_domains
|
||||
ipset=/bellingcat.com/vpn_domains
|
||||
ipset=/bestbuy.com/vpn_domains
|
||||
ipset=/bestchange.ru/vpn_domains
|
||||
ipset=/bihus.info/vpn_domains
|
||||
ipset=/bitdefender.com/vpn_domains
|
||||
ipset=/blackseanews.net/vpn_domains
|
||||
@@ -700,6 +702,7 @@ ipset=/twtrdns.net/vpn_domains
|
||||
ipset=/twttr.com/vpn_domains
|
||||
ipset=/twttr.net/vpn_domains
|
||||
ipset=/twvid.com/vpn_domains
|
||||
ipset=/typing.com/vpn_domains
|
||||
ipset=/ui.ill.in.ua/vpn_domains
|
||||
ipset=/ukr.net/vpn_domains
|
||||
ipset=/ukr.radio/vpn_domains
|
||||
|
||||
@@ -66,10 +66,12 @@ nftset=/baikal-journal.ru/4#inet#fw4#vpn_domains
|
||||
nftset=/bato.to/4#inet#fw4#vpn_domains
|
||||
nftset=/bbc.co.uk/4#inet#fw4#vpn_domains
|
||||
nftset=/bbc.com/4#inet#fw4#vpn_domains
|
||||
nftset=/bbci.co.uk/4#inet#fw4#vpn_domains
|
||||
nftset=/bcbits.com/4#inet#fw4#vpn_domains
|
||||
nftset=/bell-sw.com/4#inet#fw4#vpn_domains
|
||||
nftset=/bellingcat.com/4#inet#fw4#vpn_domains
|
||||
nftset=/bestbuy.com/4#inet#fw4#vpn_domains
|
||||
nftset=/bestchange.ru/4#inet#fw4#vpn_domains
|
||||
nftset=/bihus.info/4#inet#fw4#vpn_domains
|
||||
nftset=/bitdefender.com/4#inet#fw4#vpn_domains
|
||||
nftset=/blackseanews.net/4#inet#fw4#vpn_domains
|
||||
@@ -700,6 +702,7 @@ nftset=/twtrdns.net/4#inet#fw4#vpn_domains
|
||||
nftset=/twttr.com/4#inet#fw4#vpn_domains
|
||||
nftset=/twttr.net/4#inet#fw4#vpn_domains
|
||||
nftset=/twvid.com/4#inet#fw4#vpn_domains
|
||||
nftset=/typing.com/4#inet#fw4#vpn_domains
|
||||
nftset=/ui.ill.in.ua/4#inet#fw4#vpn_domains
|
||||
nftset=/ukr.net/4#inet#fw4#vpn_domains
|
||||
nftset=/ukr.radio/4#inet#fw4#vpn_domains
|
||||
|
||||
@@ -65,10 +65,12 @@ baikal-journal.ru
|
||||
bato.to
|
||||
bbc.co.uk
|
||||
bbc.com
|
||||
bbci.co.uk
|
||||
bcbits.com
|
||||
bell-sw.com
|
||||
bellingcat.com
|
||||
bestbuy.com
|
||||
bestchange.ru
|
||||
bihus.info
|
||||
bitdefender.com
|
||||
blackseanews.net
|
||||
@@ -634,7 +636,6 @@ svtv.org
|
||||
swagger.io
|
||||
swissinfo.ch
|
||||
synoforum.com
|
||||
t.co
|
||||
tableau.com
|
||||
tayga.info
|
||||
te-st.org
|
||||
@@ -699,7 +700,7 @@ twtrdns.net
|
||||
twttr.com
|
||||
twttr.net
|
||||
twvid.com
|
||||
ua
|
||||
typing.com
|
||||
ui.ill.in.ua
|
||||
ukr.net
|
||||
ukr.radio
|
||||
|
||||
@@ -66,10 +66,12 @@
|
||||
/ip dns static add name=bato.to type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bbc.co.uk type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bbc.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bbci.co.uk type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bcbits.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bell-sw.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bellingcat.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bestbuy.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bestchange.ru type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bihus.info type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=bitdefender.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=blackseanews.net type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
@@ -700,6 +702,7 @@
|
||||
/ip dns static add name=twttr.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=twttr.net type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=twvid.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=typing.com type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=ui.ill.in.ua type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=ukr.net type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
/ip dns static add name=ukr.radio type=FWD address-list=allow-domains match-subdomain=yes forward-to=localhost
|
||||
|
||||
@@ -66,10 +66,12 @@ baikal-journal.ru
|
||||
bato.to
|
||||
bbc.co.uk
|
||||
bbc.com
|
||||
bbci.co.uk
|
||||
bcbits.com
|
||||
bell-sw.com
|
||||
bellingcat.com
|
||||
bestbuy.com
|
||||
bestchange.ru
|
||||
bihus.info
|
||||
bitdefender.com
|
||||
blackseanews.net
|
||||
@@ -700,6 +702,7 @@ twtrdns.net
|
||||
twttr.com
|
||||
twttr.net
|
||||
twvid.com
|
||||
typing.com
|
||||
ui.ill.in.ua
|
||||
ukr.net
|
||||
ukr.radio
|
||||
|
||||
9
Subnets/IPv4/telegram.lst
Normal file
9
Subnets/IPv4/telegram.lst
Normal file
@@ -0,0 +1,9 @@
|
||||
91.108.56.0/22
|
||||
91.108.4.0/22
|
||||
91.108.8.0/22
|
||||
91.108.16.0/22
|
||||
91.108.12.0/22
|
||||
149.154.160.0/20
|
||||
91.105.192.0/23
|
||||
91.108.20.0/22
|
||||
185.76.151.0/24
|
||||
5
Subnets/IPv6/telegram.lst
Normal file
5
Subnets/IPv6/telegram.lst
Normal file
@@ -0,0 +1,5 @@
|
||||
2001:b28:f23d::/48
|
||||
2001:b28:f23f::/48
|
||||
2001:67c:4e8::/48
|
||||
2001:b28:f23c::/48
|
||||
2a0a:f280::/32
|
||||
115
convert.py
115
convert.py
@@ -19,6 +19,7 @@ uaDomainsOut='Ukraine/inside'
|
||||
DiscordSubnets = 'Subnets/IPv4/discord.lst'
|
||||
MetaSubnets = 'Subnets/IPv4/meta.lst'
|
||||
TwitterSubnets = 'Subnets/IPv4/twitter.lst'
|
||||
TelegramSubnets = 'Subnets/IPv4/telegram.lst'
|
||||
|
||||
def raw(src, out):
|
||||
domains = set()
|
||||
@@ -133,6 +134,7 @@ def kvas(src, out, remove={'google.com'}):
|
||||
if not tldextract.extract(line).domain and tldextract.extract(line).suffix:
|
||||
domains.add(tldextract.extract(line.rstrip()).suffix)
|
||||
|
||||
domains = domains - remove
|
||||
domains = sorted(domains)
|
||||
|
||||
with open(f'{out}-kvas.lst', 'w') as file:
|
||||
@@ -188,7 +190,7 @@ def generate_srs_domains(domains, output_name):
|
||||
os.makedirs(compiled_output_directory, exist_ok=True)
|
||||
|
||||
data = {
|
||||
"version": 2,
|
||||
"version": 3,
|
||||
"rules": [
|
||||
{"domain_suffix": domains}
|
||||
]
|
||||
@@ -215,8 +217,12 @@ def generate_srs_for_categories(directories, output_json_directory='JSON', compi
|
||||
os.makedirs(output_json_directory, exist_ok=True)
|
||||
os.makedirs(compiled_output_directory, exist_ok=True)
|
||||
|
||||
exclude = {"meta", "twitter", "discord"}
|
||||
|
||||
for directory in directories:
|
||||
for filename in os.listdir(directory):
|
||||
if any(keyword in filename for keyword in exclude):
|
||||
continue
|
||||
file_path = os.path.join(directory, filename)
|
||||
|
||||
if os.path.isfile(file_path):
|
||||
@@ -228,7 +234,7 @@ def generate_srs_for_categories(directories, output_json_directory='JSON', compi
|
||||
domains.append(domain)
|
||||
|
||||
data = {
|
||||
"version": 2,
|
||||
"version": 3,
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": domains
|
||||
@@ -266,28 +272,14 @@ def generate_srs_subnets(input_file, output_json_directory='JSON', compiled_outp
|
||||
subnet = line.strip()
|
||||
if subnet:
|
||||
subnets.append(subnet)
|
||||
|
||||
if input_file == "Subnets/IPv4/discord.lst":
|
||||
data = {
|
||||
"version": 2,
|
||||
"rules": [
|
||||
{
|
||||
"network": ["udp"],
|
||||
"ip_cidr": subnets,
|
||||
"port_range": ["50000:65535"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
else:
|
||||
data = {
|
||||
"version": 2,
|
||||
"rules": [
|
||||
{
|
||||
"ip_cidr": subnets
|
||||
}
|
||||
]
|
||||
}
|
||||
data = {
|
||||
"version": 3,
|
||||
"rules": [
|
||||
{
|
||||
"ip_cidr": subnets
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
filename = os.path.splitext(os.path.basename(input_file))[0]
|
||||
output_file_path = os.path.join(output_json_directory, f"{filename}_subnets.json")
|
||||
@@ -306,6 +298,63 @@ def generate_srs_subnets(input_file, output_json_directory='JSON', compiled_outp
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Compile error {output_file_path}: {e}")
|
||||
|
||||
def generate_srs_combined(input_subnets_file, input_domains_file, output_json_directory='JSON', compiled_output_directory='SRS'):
|
||||
os.makedirs(output_json_directory, exist_ok=True)
|
||||
os.makedirs(compiled_output_directory, exist_ok=True)
|
||||
|
||||
domains = []
|
||||
if os.path.exists(input_domains_file):
|
||||
with open(input_domains_file, 'r', encoding='utf-8') as file:
|
||||
domains = [line.strip() for line in file if line.strip()]
|
||||
|
||||
subnets = []
|
||||
if os.path.exists(input_subnets_file):
|
||||
with open(input_subnets_file, 'r', encoding='utf-8') as file:
|
||||
subnets = [line.strip() for line in file if line.strip()]
|
||||
|
||||
if input_subnets_file == "Subnets/IPv4/discord.lst":
|
||||
data = {
|
||||
"version": 3,
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": domains
|
||||
},
|
||||
{
|
||||
"network": ["udp"],
|
||||
"ip_cidr": subnets,
|
||||
"port_range": ["50000:65535"]
|
||||
}
|
||||
]
|
||||
}
|
||||
else:
|
||||
data = {
|
||||
"version": 3,
|
||||
"rules": [
|
||||
{
|
||||
"domain_suffix": domains,
|
||||
"ip_cidr": subnets
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
filename = os.path.splitext(os.path.basename(input_subnets_file))[0]
|
||||
output_file_path = os.path.join(output_json_directory, f"{filename}.json")
|
||||
|
||||
with open(output_file_path, 'w', encoding='utf-8') as output_file:
|
||||
json.dump(data, output_file, indent=4)
|
||||
|
||||
print(f"JSON file generated: {output_file_path}")
|
||||
|
||||
srs_file_path = os.path.join(compiled_output_directory, f"{filename}.srs")
|
||||
try:
|
||||
subprocess.run(
|
||||
["sing-box", "rule-set", "compile", output_file_path, "-o", srs_file_path], check=True
|
||||
)
|
||||
print(f"Compiled .srs file: {srs_file_path}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Compile error {output_file_path}: {e}")
|
||||
|
||||
|
||||
def prepare_dat_domains(domains_or_dirs, output_name):
|
||||
output_lists_directory = 'geosite_data'
|
||||
|
||||
@@ -335,17 +384,19 @@ def generate_dat_domains(data_path='geosite_data', output_name='geosite.dat', ou
|
||||
try:
|
||||
subprocess.run(
|
||||
["domain-list-community", f"-datapath={data_path}", f"-outputname={output_name}", f"-outputdir={output_directory}"],
|
||||
check=True
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL
|
||||
)
|
||||
print(f"Compiled .dat file: {output_directory}/{output_name}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Compile error geosite.dat: {e}")
|
||||
print(f"Compile error {data_path}: {e}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Russia inside
|
||||
Path("Russia").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
removeDomains = {'google.com', 'googletagmanager.com', 'github.com', 'githubusercontent.com', 'githubcopilot.com', 'microsoft.com', 'cloudflare-dns.com', 'parsec.app' }
|
||||
removeDomainsKvas = {'google.com', 'googletagmanager.com', 'github.com', 'githubusercontent.com', 'githubcopilot.com', 'microsoft.com', 'cloudflare-dns.com', 'parsec.app', 't.co' }
|
||||
removeDomainsKvas = {'google.com', 'googletagmanager.com', 'github.com', 'githubusercontent.com', 'githubcopilot.com', 'microsoft.com', 'cloudflare-dns.com', 'parsec.app', 't.co', 'ua' }
|
||||
|
||||
inside_lists = [rusDomainsInsideCategories, rusDomainsInsideServices]
|
||||
|
||||
@@ -394,12 +445,14 @@ if __name__ == '__main__':
|
||||
generate_srs_for_categories(directories)
|
||||
|
||||
# Sing-box subnets
|
||||
generate_srs_subnets(DiscordSubnets)
|
||||
generate_srs_subnets(TwitterSubnets)
|
||||
generate_srs_subnets(MetaSubnets)
|
||||
generate_srs_subnets(TelegramSubnets)
|
||||
|
||||
generate_srs_combined(DiscordSubnets, "Services/discord.lst")
|
||||
generate_srs_combined(TwitterSubnets, "Services/twitter.lst")
|
||||
generate_srs_combined(MetaSubnets, "Services/meta.lst")
|
||||
|
||||
# Xray domains
|
||||
prepare_dat_domains(directories, 'russia-inside')
|
||||
prepare_dat_domains(russia_outside, 'russia-outside')
|
||||
prepare_dat_domains(ukraine_inside, 'ukraine-inside')
|
||||
generate_dat_domains()
|
||||
generate_dat_domains()
|
||||
|
||||
@@ -15,6 +15,7 @@ AS_META = '32934'
|
||||
AS_TWITTER = '13414'
|
||||
META = 'meta.lst'
|
||||
TWITTER = 'twitter.lst'
|
||||
TELEGRAM = 'telegram.lst'
|
||||
|
||||
# From https://iplist.opencck.org/
|
||||
DISCORD_VOICE_V4='https://iplist.opencck.org/?format=text&data=cidr4&site=discord.gg&site=discord.media'
|
||||
@@ -22,6 +23,8 @@ DISCORD_VOICE_V6='https://iplist.opencck.org/?format=text&data=cidr6&site=discor
|
||||
|
||||
DISCORD = 'discord.lst'
|
||||
|
||||
TELEGRAM_CIDR_URL = 'https://core.telegram.org/resources/cidr.txt'
|
||||
|
||||
subnet_list = []
|
||||
|
||||
def subnet_summarization(subnet_list):
|
||||
@@ -76,6 +79,15 @@ def download_ready_subnets(url_v4, url_v6):
|
||||
|
||||
return ipv4_subnets, ipv6_subnets
|
||||
|
||||
def download_ready_split_subnets(url):
|
||||
req = urllib.request.Request(url)
|
||||
with urllib.request.urlopen(req) as response:
|
||||
subnets = response.read().decode('utf-8').splitlines()
|
||||
|
||||
ipv4_subnets = [cidr for cidr in subnets if isinstance(ipaddress.ip_network(cidr, strict=False), ipaddress.IPv4Network)]
|
||||
ipv6_subnets = [cidr for cidr in subnets if isinstance(ipaddress.ip_network(cidr, strict=False), ipaddress.IPv6Network)]
|
||||
|
||||
return ipv4_subnets, ipv6_subnets
|
||||
|
||||
def write_subnets_to_file(subnets, filename):
|
||||
with open(filename, 'w') as file:
|
||||
@@ -111,6 +123,11 @@ if __name__ == '__main__':
|
||||
write_subnets_to_file(ipv4_discord, f'{IPv4_DIR}/{DISCORD}')
|
||||
write_subnets_to_file(ipv6_discord, f'{IPv6_DIR}/{DISCORD}')
|
||||
|
||||
# Telegram
|
||||
ipv4_telegram, ipv6_telegram = download_ready_split_subnets(TELEGRAM_CIDR_URL)
|
||||
write_subnets_to_file(ipv4_telegram, f'{IPv4_DIR}/{TELEGRAM}')
|
||||
write_subnets_to_file(ipv6_telegram, f'{IPv6_DIR}/{TELEGRAM}')
|
||||
|
||||
# Legacy name
|
||||
copy_file_legacy(f'{IPv4_DIR}/{META}')
|
||||
copy_file_legacy(f'{IPv6_DIR}/{META}')
|
||||
|
||||
Reference in New Issue
Block a user