Во-первых, вам не хватает \r\n
в конце вашего фальшивого ответа, который необходим линии соответствия.
Другая важная проблема заключается в том, что ваша программа обрабатывает только одно соединение, а затем закрывается. Nmap сначала выполнит сканирование порта, а затем отправит сервисные дактилоскопические зонды. Если вы запустите nmap от имени пользователя root (или администратора в Windows), он будет использовать полуоткрытое сканирование TCP SYN, и ваше приложение не увидит сканирование портов как соединение, но в противном случае оно примет сканирование портов, закроет соединение и быть недоступным для фазы сканирования службы.
Вот очень базовая адаптация вашего скрипта, которая может обрабатывать последовательные соединения (но не параллельные), чего достаточно, чтобы обмануть Nmap:
import socket
s = socket.socket( )
s.bind(('', 21))
s.listen(1)
while True:
conn, addr = s.accept()
conn.send("220-GuildFTPd FTP Server (c) 1997-2002\r\n220-Version 0.999.14\r\n")
conn.close()