I started a MongoDB server mongod.exe on my local Win11 machine and want to connect to it with pymongo from within WSL2 (from a Jupyter Notebook started in WSL2; ip address taken from ifconfig below):
import pymongo as pm
import datetime as dt
host = 'mongodb://192.168.72.32'
port = 27017
client = pm.MongoClient(host, port)
client.admin.command('ismaster')
I keep on getting a ServerSelectionTimeoutError: 192.168.72.32:27017: [Errno 111] Connection refused error.
The problem is how to expose the server/port from Windows to WSL2. I already opened ports in netsh (as described in official docs here). Output from ifconfig on WSL2 end:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.72.32 netmask 255.255.240.0 broadcast 192.168.79.255
inet6 fe80::215:5dff:fe96:9d57 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:96:9d:57 txqueuelen 1000 (Ethernet)
RX packets 662495 bytes 168890186 (168.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 170242 bytes 369162848 (369.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 99019 bytes 163040786 (163.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 99019 bytes 163040786 (163.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
What am I doing wrong?
There are (at least) three things that need to be in place to access any network application/service running in Windows from WSL2:
*Configure the service to listen on the correct Windows network interface (not localhost), a.k.a. the "bind address".
Open the necessary firewall port(s)
Use the correct address from WSL2 (again, not localhost)
You may just be missing the first part, as MongoDB binds to localhost by default. According to the doc:
MongoDB binaries, mongod and mongos, bind to localhost by default. If the net.ipv6 configuration file setting or the --ipv6 command line option is set for the binary, the binary additionally binds to the localhost IPv6 address.
More detail provided below on each of these requirements (mostly copied, with some slight tweaks for your particular use-case, from my related answer on Super User):
Bind address
Many applications or services default to binding to localhost, which (obviously) means that you can only connect to them from the host on which the service is running. Because WSL2 runs on a "separate network", you won't be able to access a service in Windows that is listening only on localhost. You'll probably want to bind to 0.0.0.0 (for IPv4) and/or :: (for IPv6) to listen on all interfaces.
The method of configuring the service will, of course, vary for different applications, but usually you'll find the setting labeled something like "Bind Address", "Listen On", or something similar. Instructions for MongoDB specifically are linked above.
Make sure to restart the application/service after changing this setting.
Side note: It's possible to bind only to the WSL2 interface as I describe in this answer (buried somewhere in the middle), but it's probably overkill, as the firewall can be used more easily to block connections from non-WSL networks if desired.
Firewall configuration
By default, Windows Defender Firewall (and others) will block incoming connections to the host from another network. Since we've already established that WSL2 is running in a separate network, you'll need to open a firewall port for your service.
You can do this selectively from PowerShell (in an Administrative shell) with something like:
New-NetFirewallRule -DisplayName "MongoDB from WSL2" -InterfaceAlias "vEthernet (WSL)" -Direction Inbound -Protocol TCP -LocalPort 27017 -Action Allow
Of course, you can drop either:
the InterfaceAlias, in which case it will open 8545 from all networks
or the LocalPort, in which case it will act like the "disable" option above and always accept incoming traffic from the WSL network interface.
Finding the correct Windows address to use from WSL2
There are several methods (and IP addresses) you can use. The easiest way is simply to use the IP address of the Windows host, if you know it. However, if it is dynamically assigned and changes frequently (which is, I believe, fairly unusual nowaways), then you may need to change your WSL2 code each reboot.
In your case, it looks like you likely have a static address in the 192.168.0.0/32 private address space, so you may not need the following.
However, it's probably best practice anyway to use a mDNS name that will (usually) resolve correctly for static or dynamic address assignments.
Assuming that you haven't overridden the default /etc/resolv.conf that WSL generates, this can be done by taking the Windows computer name and simply appending .local. For instance, if your computer name is bubblegum, then bubblegum.local should be the correct address.
From Python, this can be obtained with:
import socket
server = f'{socket.gethostname()}.local' # Generic form
host = f'mongodb://{socket.gethostname()}.local' # For your example
You should find that this is the same address as found with:
echo $(ip route list default | awk '{print $3}')
If, however, you have overridden the /etc/resolv.conf (necessary in some cases due to VPNs or other networking configurations), then you may need something more complicated like:
echo $(host `hostname --long` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')
(Credit to #ChaiAng's answer on Ask Ubuntu for this method).
However, note that it is substantially slower than mDNS.
Related
I currently have two different 5g routers. My PC's wifi doesn't work, so I'm only able to connect either of them through wired connection. The old one that I want to get rid of uses a usb, and works. The new one uses ethernet, and fails with DNS lookup (ping www.google.com fails but ping 8.8.8.8 succeeds.)
resolve.conf looks like:
# Generated by NetworkManager
search lan
nameserver 192.168.1.1
nameserver fe80::d4bb:5cff:fe4e:6313
nameserver fe80::38:40ff:fe30:419e
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver fe80::34e1:ffff:fe65:f72b
nameserver fe80::d43f:21ff:fe59:462a
nameserver 192.168.12.1
nameserver fe80::ca99:b2ff:fee7:71f5%enp5s0
nameserver fe80::d43f:21ff:fe59:462a%enp6s0f1u1
nmcli yields:
enp5s0: connected to Wired connection 1
"Intel I211"
ethernet (igb), 3C:7C:3F:1E:C6:01, hw, mtu 1500
ip4 default, ip6 default
inet4 192.168.12.232/24
route4 192.168.12.0/24 metric 100
route4 default via 192.168.12.1 metric 100
inet6 2607:fb90:3307:6e5d:91df:e64b:949:c78c/128
inet6 2607:fb90:3307:6e5d:bcb3:1b35:1589:bd17/64
inet6 fe80::48f9:3fb0:7e83:d1a7/64
route6 2607:fb90:3307:6e5d:91df:e64b:949:c78c/128 metric 100
route6 2607:fb90:3307:6e5d::/64 metric 100
route6 fe80::/64 metric 1024
route6 default via fe80::ca99:b2ff:fee7:71f5 metric 100
enp6s0f1u1: connected to Wired connection 2
"Novatel Wireless M2000"
ethernet (rndis_host), 00:15:FF:30:51:72, hw, mtu 1428
inet4 192.168.1.5/24
route4 192.168.1.0/24 metric 101
route4 default via 192.168.1.1 metric 101
inet6 2607:fb90:3395:673a:5552:7f52:abd9:488e/64
inet6 fe80::20b0:4b16:c9f:e9d0/64
route6 fe80::/64 metric 1024
route6 2607:fb90:3395:673a::/64 metric 101
route6 default via fe80::d43f:21ff:fe59:462a metric 101
"Wired connection 2" is the one that works (the USB one.)
So I'm pretty clear that my resolv.conf is specifically telling the usb interface to use one DNS server (fe80::d43f:21ff:fe59:462a) that works, and telling the ethernet interface to use another (fe80::ca99:b2ff:fee7:71f5) that fails. I just don't know why it's doing that, or how to make it stop (given that I think NetworkManager generates that file, and will presumably re-generate it if I just edit it myself.)
What happen? What do?
Recently I found that I was able to bind Apache on 127.0.0.73 without 127.0.0.73 to be present.
Only 127.0.0.1 is present as normal.
I also spoke with a friend and he said that is "normal" on Linux and probably on Windows and not works on MacOS, but he has no idea why.
I can do following:
[nmmm#zenbook nmmm]$ curl 127.10.0.123
curl: (7) Failed to connect to 127.10.0.123 port 80: Connection refused
and it shows that whole A class network is available.
How this works?
I do not see anything special in ifconfig and ip, except lo interface has no broadcast. Is that the key point?
According to https://en.wikipedia.org/wiki/Localhost
IPv4 network standards reserve the entire address block 127.0.0.0/8 (more than 16 million addresses) for loopback purposes.2 That means any packet sent to any of those addresses is looped back. The address 127.0.0.1 is the standard address for IPv4 loopback traffic; the rest are not supported by all operating systems. However they can be used to set up multiple server applications on the host, all listening on the same port number. The IPv6 standard assigns only a single address for loopback: ::1.
Or from https://www.rfc-editor.org/rfc/rfc3330
127.0.0.0/8 - This block is assigned for use as the Internet host
loopback address. A datagram sent by a higher level protocol to an
address anywhere within this block should loop back inside the host.
Even though you can't see anything from ifconfig or ip, you still can ping all the addresses in that 127.0.0.0/8 block.
How to get interface name from IPv4 ip address using only filesystem like /proc, /dev, /sys and bash? Is this possible without using the commands (such as ip, ifconfig, etc.)? I am also not able to use any packages or install any tools.
Edit:
The reason for this is I am trying to get host's interface names and ip addresses from within a Docker container. The container is mounted with host's root and has access to host's filesystem. However, since the container is in a separate namespace, ip commands (and other similar command such as ifconfig) will only return the container's network. Hence, I believe the only way of getting the host's interface names and ip addresses is through the host's root (/hostroot/proc, /hostroot/sys, etc.). Note that I cannot have the --net=host flag when starting the container (which tells the container to use the host's net namespace).
I tried finding all my network interface IP addresses (IPv4) from the /proc/net/fib_trie file. I read at https://regexit.com/3-ways-to-get-your-ip-on-a-linux-system/ which basically says that I can do cat /proc/net/fib_trie | grep -B 1 "32 host LOCAL" to find the IP addresses. I also see in https://stackoverflow.com/a/42082822 , that we can filter the fib_trie by pattern matching the string "32 host" to get the local network interface addresses. After getting the IP addresses from the above method (using the /proc/net/fib_trie), I try to match those IP address with the "destination" IP address in /proc/net/route to get the network interface name. However, my /proc/net/route contains multiple entry for some interfaces (such as enp0s3). For example, there are two enp0s3 entries with different IP addresss ("Destination column). Moreover, the network interfaces in route file does have ip close to what is indicated by the ip command but not exactly.
Is there a better way of getting the network interface name after getting the IP address from fib_trie?
Output I need will be all the host's network interface name and corresponding IPv4 IP addresses.
I think you have sufficient information there. The /proc/net/route file doesn't really list addresses. It's supposed to tell you how to route packets. But you can glean information about the interfaces from it. On my system (ubuntu 14 so different interface name format but otherwise should be similar), it shows this:
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
eth0 00000000 0100A8C0 0003 0 0 0 00000000 0 0 0
eth0 0000A8C0 00000000 0001 0 0 1 00FFFFFF 0 0 0
eth1 0028A8C0 00000000 0001 0 0 1 00FFFFFF 0 0 0
The destination and mask fields are in hexadecimal -- and byte-reversed on little-endian machine -- and give you the range of the network. Interpretation is:
Anything destined for the 192.168.0.0/24 network (0000A8C0 + 00FFFFFF) goes to eth0 with no gateway needed (in other words, it's on the same subnet as this machine).
Anything destined for 192.168.40.0/24 (0028A8C0 + 00FFFFFF) goes to eth1 with no gateway needed.
Packets destined for any other address (00000000 + 00000000) go to the default gateway 192.168.0.1. (Not sure; it's possible that the extra flag bit or the "metric" value in this line marks this as a default gateway. But in any case, if it doesn't have a non-zero mask or is in the 0.0.0.0 address range, it's not going to be useful for routing in the real world.)
From this I can infer that my system has IP addresses in the 192.168.0.0/24 and 192.168.40.0/24 networks. The output from the grep command on /proc/net/fib_trie shows on my system:
|-- 127.0.0.1
/32 host LOCAL
|-- 192.168.0.104
/32 host LOCAL
|-- 192.168.40.129
/32 host LOCAL
So that makes it clear that my local IP addresses are 192.168.0.104 (eth0) and 192.168.40.129 (eth1). (We can ignore 127.0.0.1; it's always the loopback interface.)
I have a problem:
When I try to connect to a network, initially with ifconfig eth2 I get (correctly):
eth2 inet addr:192.168.1.56 ....
inet6 addr: fe80:221:ff:fe96:4598/64
but after a few seconds the 102.168.1.56 disappears and after some other seconds disappears the inet6 address too. In this case the network is wireless and no DHCP.
At uni, the connection is a DHCP one. It works for the first few seconds but after it doesn't.
Any possible solution?
Whats this 102.168.1.56?
cat /var/log/syslog will give more info about what happening in the system. Usually it contains large amount of information.
I'm using Samba and windbindd on my linux boxes. Without a firewall up on the linux box I have no trouble resolving LAN machine names:
user#laptop-linux:~$ ping desktop
PING desktop (192.168.1.100) 56(84) bytes of data.
64 bytes from 192.168.1.100: icmp_seq=1 ttl=128 time=0.878 ms
when I start the firewall I get:
user#laptop-linux:~$ ping desktop
ping: unknown host desktop
I have opened up the Samba ports (137-139 445) as well as the mDNS port 5353 with no effect. WINS has been enabled in nsswitch.conf and I've also tried removing the mdns4 entries for host lookup. I can see the DNS query going out regular DNS with my ISP domain suffix attached which is not what I want. I want to use wins / NetBIOS to do the work. Do I have allow some form of broadcast port? Can this be done while maintaining security? I want to have a firewall running on my laptop because I access open hotspots on a regular basis. Thanks
Sorry for necroing this post, but i had considerable trouble figuring this out, and hence am putting it up for anyone else who might run into it.
Basically you have to enable incoming packets (NB response packets) coming from port 137/udp of the responding system. In ubuntu 11.04, using ufw, this can be easily done as:
ufw allow proto udp from 192.168.1.0/24 port 137 to any
This assumes that your LAN is using the 192.168.1.0/24 ip range.