more reliable protection from replay attacks

This commit is contained in:
Alexander Bersenev
2019-05-30 14:36:24 +05:00
parent a9e12bb1bb
commit 312539c3b8

View File

@@ -51,8 +51,8 @@ USER_MAX_TCP_CONNS = config.get("USER_MAX_TCP_CONNS", {})
# length of used handshake randoms for active fingerprinting protection # length of used handshake randoms for active fingerprinting protection
REPLAY_CHECK_LEN = config.get("REPLAY_CHECK_LEN", 32768) REPLAY_CHECK_LEN = config.get("REPLAY_CHECK_LEN", 32768)
# block short first packets to even more protect against replay-based fingerprinting # block bad first packets to even more protect against replay-based fingerprinting
BLOCK_SHORT_FIRST_PKT = config.get("BLOCK_SHORT_FIRST_PKT", False) BLOCK_IF_FIRST_PKT_BAD = config.get("BLOCK_IF_FIRST_PKT_BAD", True)
# delay in seconds between stats printing # delay in seconds between stats printing
STATS_PRINT_PERIOD = config.get("STATS_PRINT_PERIOD", 600) STATS_PRINT_PERIOD = config.get("STATS_PRINT_PERIOD", 600)
@@ -1020,7 +1020,7 @@ async def handle_client(reader_clt, writer_clt):
else: else:
return return
async def connect_reader_to_writer(rd, wr, user, rd_buf_size, block_short_first_pkt=False): async def connect_reader_to_writer(rd, wr, user, rd_buf_size, block_if_first_pkt_bad=False):
is_first_pkt = True is_first_pkt = True
try: try:
while True: while True:
@@ -1030,18 +1030,17 @@ async def handle_client(reader_clt, writer_clt):
else: else:
extra = {} extra = {}
# protection against replay-based fingerprinting
if is_first_pkt: if is_first_pkt:
# protection against replay-based fingerprinting is_first_pkt = False
MIN_FIRST_PKT_SIZE = 12
if block_short_first_pkt and 0 < len(data) < MIN_FIRST_PKT_SIZE: ERR_PKT_DATA = b'l\xfe\xff\xff'
# print_err("Active fingerprinting detected from %s, dropping it" % cl_ip) if block_if_first_pkt_bad and data == ERR_PKT_DATA:
# print_err("If this causes problems set BLOCK_SHORT_FIRST_PKT = False " print_err("Active fingerprinting detected from %s, dropping it" % cl_ip)
# "in the config")
wr.write_eof() wr.write_eof()
await wr.drain() await wr.drain()
return return
is_first_pkt = False
if not data: if not data:
wr.write_eof() wr.write_eof()
@@ -1056,7 +1055,7 @@ async def handle_client(reader_clt, writer_clt):
pass pass
tg_to_clt = connect_reader_to_writer(reader_tg, writer_clt, user, get_to_clt_bufsize(), tg_to_clt = connect_reader_to_writer(reader_tg, writer_clt, user, get_to_clt_bufsize(),
block_short_first_pkt=BLOCK_SHORT_FIRST_PKT) block_if_first_pkt_bad=BLOCK_IF_FIRST_PKT_BAD)
clt_to_tg = connect_reader_to_writer(reader_clt, writer_tg, user, get_to_tg_bufsize()) clt_to_tg = connect_reader_to_writer(reader_clt, writer_tg, user, get_to_tg_bufsize())
task_tg_to_clt = asyncio.ensure_future(tg_to_clt) task_tg_to_clt = asyncio.ensure_future(tg_to_clt)
task_clt_to_tg = asyncio.ensure_future(clt_to_tg) task_clt_to_tg = asyncio.ensure_future(clt_to_tg)