Net::SMTP can't connect on Windows 8 - linux

I wrote a minuscule script to test an SMTP connection with Net::SMTP:
#!/usr/bin/perl -w
use strict;
use Net::SMTP;
my $smtp = Net::SMTP->new( 'mypc', Port => 10025, Timeout => 30, Debug => 1 );
die "Couldn't connect to SMTP server" unless $smtp;
An SMTP server is running on mypc:10025 and dumps all I/O it does. When I execute the script from a Debian Linux machine (64bit, Perl v5.20.2), the SMTP server shows I/O activity and everything works as expected:
zb226#debian8:~$ ./net_smtp.pl
Net::SMTP>>> Net::SMTP(2.33)
Net::SMTP>>> Net::Cmd(2.30)
Net::SMTP>>> Exporter(5.71)
Net::SMTP>>> IO::Socket::INET(1.35)
Net::SMTP>>> IO::Socket(1.38)
Net::SMTP>>> IO::Handle(1.35)
Net::SMTP=GLOB(0x118adc0)<<< 220 Hi
Net::SMTP=GLOB(0x118adc0)>>> EHLO localhost.localdomain
Net::SMTP=GLOB(0x118adc0)<<< 250 OK
When I execute this on the Windows 8 machine (64bit, Strawberry Perl 5.22.0), no connection is established. I can see this by the total absence of I/O in the SMTP server. Net::SMTP does not connect. The script just dies, as is expected in this case:
C:\test>perl -w net_smtp.pl
Couldn't connect to SMTP server at net_smtp.pl line 5.
Observations:
Interestingly, the script dies after what feels like 3 seconds, not the 30 seconds I specified.
I can use telnet.exe to connect to the SMTP server and it shows I/O activity.
I have tried turning off the Windows firewall completely without any improvement.
I had an admin disable the corporate anti-virus software temporarily without any improvement.
Updating Strawberry Perl to the currently recommended 5.24.0.1 didn't help either.
I'm not sure what to try next.
Edit: Tried a small IO::Socket::INET script to verify perl can actually connect on this Windows PC:
#!/usr/bin/perl
use strict;
use IO::Socket::INET;
my #hosts = qw/ mypc:10025 /;
foreach my $host ( #hosts ) {
my $open = defined IO::Socket::INET->new(PeerAddr => $host, Timeout => 5) || 0;
printf "Probed %s -> %s \n", $host, $open ? 'ok' : 'NOK';
}
I see I/O in the SMTP server and it works as expected:
C:\test>perl -w io_socket.pl
Probed mypc:10025 -> ok

Based on the information from the other answer the underlying problem is, that
the hostname used resolves to both an IPv4 and IPv6 address,
the SMTP server is only listening at the IPv4 address or the IPv6 address is blocked by a firewall,
and a recent version of Net::SMTP is in use which contrary to older versions transparently supports IPv6 and IPv4.
Because if the IPv6 support and the commonly used preference for the newer IPv6 against IPv4 Net::SMTP will resolve the hostname and then try the IPv6 address - and fail to connect. Direct use of IO::Socket::INET instead works because it is doing only IPv4 (contrary to IO::Socket::IP used by Net::SMTP).
The reason it works on Linux and not on Windows is probably the different version of Perl: the new version of Net::SMTP with built-in IPv6 (and SSL) support ships only since Perl 5.22 as a CORE module, i.e. the Perl on Windows (5.22) has the version with IPv6 support while the Perl on Linux (5.20) does not.
There are several ways to fix the problem:
use the IPv4 address directly instead of the hostname
make the SMTP server listen on both IPv4 and IPv6
or specify the address family to use, i.e.
my $smtp = Net::SMTP->new( 'mypc', ..., Domain => AF_INET );

Following this discussion, I found that the problem is related to IPv6. Opening C:\strawberry\perl\lib\Net\SMTP.pm and changing the line...
our #ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
...to...
our #ISA = ('Net::Cmd', 'IO::Socket::INET');
...makes the original script run:
C:\test>perl -w net_smtp.pl
Net::SMTP>>> Net::SMTP(3.08)
Net::SMTP>>> Net::Cmd(3.08)
Net::SMTP>>> Exporter(5.72)
Net::SMTP>>> IO::Socket::INET(1.35)
Net::SMTP>>> IO::Socket(1.38)
Net::SMTP>>> IO::Handle(1.36)
Net::SMTP=GLOB(0x58e8fc)<<< 220 Hi
Net::SMTP=GLOB(0x58e8fc)>>> EHLO localhost.localdomain
Net::SMTP=GLOB(0x58e8fc)<<< 250 OK
For now, I'm relieved because I can continue my work, but if anybody has further clues as to how to avoid this ugly patch, I'll happily accept an elaborated answer.
Edit: Correspondingly and without patching, disabling IPv6 does the trick as well.

Related

python3 requests hangs when accessing port 25564 or higher on Ubuntu 20.04 LTS

I have a simple program which creates a simple web server at localhost with a random port between 10000 and 65535 (which is the highest unsigned 16-bit integer). You can also specify a port but if you don't know on which port it runs it's hard to find out.
I have written a little helper program that should show every port that's being listened to.
The helper:
import requests
for port in range(10000, 65535):
try:
print(port, requests.get("http://localhost:{}".format(port)))
except Exception as e:
print("{}: {}".format(type(e).__name__, port), end="\r")
I expect it to show ConnectionError: 10000 and counting up to 65535 and showing any found connections. But it hangs always on port 25564 25565, last showing the message for port 25564. And if I do a completely unrelated request to 'http://localhost:25564' or any higher port it hangs.
The script hangs on port 25565 when I start a server on 25564.
Normally if a port has no server listening it will immediately refuse the connection and give a ConnectionError. Above port 25564 it doesn't but just waits until I stop it.
This behaviour seems completely random as port 25564 is unassigned according to speedguide.net.
Port 25565 is the standard MySQL and Minecraft Dedicated Server port (according to speedguide.net), both of which I haven't running on my machine. Therefore the hang still seems random.
I'm using python3 on Ubuntu 20.04 LTS.
Interestingly it didn't fail on my laptop with Linux Mint 21...
As #root requested in the comments, here is the output of nmap localhost:
Starting Nmap 7.80 ( https://nmap.org ) at 2022-09-25 11:42 CEST
Host is up (0.00014s latency).
Not shown: 996 closed ports
PORT STATE SERVICE
80/tcp open http
631/tcp open ipp
8080/tcp open http-proxy
9050/tcp open tor-socks
Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds
Just a little note: port 80/tcp is listened on by apache2 with the "You are an idiot" flash animation.
As per the comments, you can try something like this:
You will note that i have added the timeout parameter in the requests. This units are in seconds. The default timeout is None, which means it'll wait (hang) until the connection is closed.
import requests
for port in range(10_000, 65_535):
try:
r = requests.get(f'http://localhost:{port}', timeout=5)
print(port)
except Exception as e:
print(f'{type(e).__name__}, {port}', end='\r')

dovecot unable to start due to address already in use

I upgraded my Linux kernel and dovecot failed to start with the following error messages:
Error: service(managesieve-login): listen(*, 4190) failed: Address already in use
Error: service(pop3-login): listen(*, 110) failed: Address already in use
Error: service(pop3-login): listen(*, 995) failed: Address already in use
Error: service(imap-login): listen(*, 143) failed: Address already in use
Error: service(imap-login): listen(*, 993) failed: Address already in use
Fatal: Failed to start listeners
Strangely enough, I couldn't find any process bounded to those port numbers. All commands below return nothing.
# netstat -tulpn | grep 110
# ss -tulpn |grep 110
# fuser 110/tcp
# lsof -i :110
I also tried to change the listen setting to my specific IP address and it still failed the same way.
Any idea how I can solve this problem? Here's my version info:
# uname -a
Linux ip-172-31-26-222 4.14.177-107.254.amzn1.x86_64 #1 SMP Thu May 7 18:30:14 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
# dovecot --version
2.2.36 (1f10bfa63)
Hi it looks like you are using AWS as I am. I recently updated via Yum as well. I noticed that a new package named 'portreserve' was also installed. I killed that process, left the /etc/dovecot/dovecot.conf as it was before and then started Dovecot successfully. I was also immediately able to reconnect my mail clients connection. I hope that helps you.
I also restarted the portreserve program since it seems useful to limit port access.

Python3.6 Scapy receives ICMP responses even from dead hosts

Got strange stuff. Setup: VirtualBox + CentOs7 + python3.6 + scapy2.4.0
Got network with only 4-5 hosts active: gateway, CentOs in VirtualBos, PC on which VirtualBox running and something else.
Trying to do:
ans, unans = sr(IP(dst='10.10.10.1-100')/ICMP(), iface = 'enp0s3', retry=0, timeout=1)
Begin emission: ...
Received 1822 packets, got 99 answers, remaining 1 packets
ans
Results: TCP:0 UDP:0 ICMP:99 Other:0
unans
Unanswered: TCP:0 UDP:0 ICMP:1 Other:0
ans[x] - are legit ICMP Reply packets.
unans[0] - no ICMP reply from CentOs VM itself
So looks like everything is alive instead of 4-5 hosts which actually are alive
What could be the possible reason ?
You want to know the possible reason, but scapy is not giving you enough details. So use tcpdump:
$ sudo tcpdump -e -c 200 icmp
Send the probe packets while tcpdump is running, in order to view address and timing details. It is possible you are seeing lots of perfectly normal ICMPs, for example port unreachable, or network unreachable. Tcpdump will tell you exactly what went over the network interface.

How to connect to Cassandra(remotehost) using cqlsh

I cannot cqlsh to remote host
./cqlsh xx.xx.x.xxx 9042
Connection error: ('Unable to connect to any servers', {'10.101.33.163':
ConnectionException(u'Did not get expected SupportedMessage response;
instead, got: <ErrorMessage code=0000 [Server error]
message="io.netty.handler.codec.DecoderException:
org.apache.cassandra.transport.ProtocolException: Invalid or unsupported
protocol version: 4">',)})
I am using cqlsh 5.0.1 and python 2.7.10
./cqlsh --version
cqlsh 5.0.1
python -V
Python 2.7.10
I am on mac and used the instructions from http://www.datastax.com/2012/01/working-with-apache-cassandra-on-mac-os-x to download cassandra.
Cassandra on my local is 2.2.1(as I understand from the zip file) and it appears like cassandra on remote host is NOT 2.2.1 (I assume it is either 2.0 or 2.1). Without definitively knowing what the version is on remote host, how can I try to connect to cassandra on remote host
1) Make sure the service is running:
$ ps aux | grep cassandra
Example:
106 7387 5.1 70.9 2019816 1454636 ? SLl Sep02 16:39 /usr/lib/jvm/java-7-oracle/jre//bin/java -Ddse.system_cpu_cores=2 -Ddse.system_memory_in_mb=2003 -Dcassandra.config.loader=com.datastax.bdp.config.DseConfigurationLoader -Ddse.system_cpu_cores=2 -Ddse.system_memory_in_mb=2003 -Dcassandra.config.loader=com.datastax.bdp.config.DseConfigurationLoader -ea -javaagen...
2) Make sure you are using the correct IP by checking the server config:
$ ifconfig
Example:
eth1 Link encap:Ethernet HWaddr 08:00:27:a6:4e:46
inet addr:192.168.56.10 Bcast:192.168.56.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fea6:4e46/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
3) Ensure you can connect to that IP from the server you are on:
$ ssh user#xxx.xxx.xx.xx
4) Check the node's status and also confirm it shows the same IP:
$nodetool status
5) run the command to connect with the IP (only specify port if you are not using the default):
$ cqlsh xxx.xxx.xx.xx
You might need to put cqlsh from 2.1 or 2.0 on your mac to match the server you are trying to connect to. So that's what I'd try first.
I was experiencing the same error (running Cassandra 2.2.0 on Windows 8.1), and found a workaround by Gustav Grusell that worked for me: https://issues.apache.org/jira/browse/CASSANDRA-9467?focusedCommentId=14693410&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14693410
The workaround he presents is to modify your cqlsh.py script to accept a protocol version. After making these changes, you will be able to specify protocol version 3 (for example) by passing --protocolversion=3 to cqlsh.
Locate cqlsh.py in your Cassandra bin folder and back it up before making these changes.
Add the following line alongside the other parser.add_option statements (~line 175):
parser.add_option("--protocolversion", default=DEFAULT_PROTOCOL_VERSION, help='Specify protocol version (default: %default).')
Add the following alongside the other optvalues under def read_options(cmdlineargs, environment): (~line 2520):
optvalues.protocolversion = option_with_default(configs.get, 'cql', 'protocolversion', DEFAULT_PROTOCOL_VERSION)
Add the following before the return statement in def read_options(cmdlineargs, environment): (~line 2574)
if options.protocolversion:
try:
options.protocolversion = int(optvalues.protocolversion)
except ValueError:
options.protocolversion=DEFAULT_PROTOCOL_VERSION
Modify the Shell command in def main(options, hostname, port): to include the protocol version (~line 2657):
connect_timeout=options.connect_timeout,
protocol_version=options.protocolversion)
Here's what my cqlsh.py now looks like: http://pastebin.com/f9D2zEE4

Linux - Syslog client

In order to develop a cross-plateform syslog client, I am trying to do it without using the syslog syscall. I am developping this client in C++ and for now testing in Linux. The old syslog client that I am replacing was working perfectly fine with the syslog syscall.
For how, it simply doesn't work. The trace is not in /var/log/user.log like it should be, either anywhere else (greped). But I do receive it when I listen on the right port with netcat. Shouldn't the port 514 be already in use by the way ?
The trace is as it should be sent on UDP/514. I tried to stick the RFC 3164 but something is still obviously wrong.
Id really appreciate if someone could give me a hint to solve this.
Trace: severity: 2 (Critical); facility: 23 (Local Use 7) ==> priority: 186
sh$> sudo nc -ul localhost -p 514
<186>Oct 18 10:36:03 hostname test_trace: | 10:36:03.242995 | CRIT | xxx-MAIN[5473-000] | 00000 | 0008 : main : user_msg
Thank you !
I think I found the problem in my own question: Rsyslog (my syslog server) doesn't listen on UDP/514 correctly.
/etc/rsyslog.conf
$ModLoad imudp
$UDPServerAddress 0.0.0.0
$UDPServerRun 514
If someone has any idea of why it still doesn't listen on UDP/514, I'd be really thanksful cause I really don't see why.
Thank you again.
The syslog() call writes to /dev/log and the system logger reads this unix domain socket to pick up the message. UDP/514 is for network transmission.
So it is not clear what you want.

Resources