Unable to bind any program to IPv4 TCP port 80 on Mac [duplicate] - macos

I have the following very simple docker-compose.yml, running on a Mac:
version: "3.7"
services:
apache:
image: httpd:2.4.41
ports:
- 80:80
I run docker-compose up, then I run this curl and Apache returns content:
/tmp/test $ curl -v http://localhost
* Trying ::1:80...
* TCP_NODELAY set
* Connected to localhost (::1) port 80 (#0)
> GET / HTTP/1.1
> Host: localhost
> User-Agent: curl/7.66.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sat, 26 Oct 2019 18:30:03 GMT
< Server: Apache/2.4.41 (Unix)
< Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT
< ETag: "2d-432a5e4a73a80"
< Accept-Ranges: bytes
< Content-Length: 45
< Content-Type: text/html
<
<html><body><h1>It works!</h1></body></html>
* Connection #0 to host localhost left intact
However, if I try to access the container using 127.0.0.1 instead of localhost, I get connection refused:
/tmp/test $ curl -v http://127.0.0.1
* Trying 127.0.0.1:80...
* TCP_NODELAY set
* Connection failed
* connect to 127.0.0.1 port 80 failed: Connection refused
* Failed to connect to 127.0.0.1 port 80: Connection refused
* Closing connection 0
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
Localhost does point to 127.0.0.1:
/tmp/test $ ping localhost
PING localhost (127.0.0.1): 56 data bytes
And netstat shows all local IP addresses port 80 to be forwarded:
/tmp/test $ netstat -tna | grep 80
...
tcp46 0 0 *.80 *.* LISTEN
...
I came to this actually trying to access the container using a custom domain I had on my /etc/hosts file pointing to 127.0.0.1. I thought there was something wrong with that domain name, but then I tried 127.0.0.1 and didn't work either, so I'm concluding there is something very basic about docker I'm not doing right.
Why is curl http://localhost working but curl http://127.0.0.1 is not?
UPDATE
It seems localhost is resolving to IPv6 ::1, so port forwarding seems to be working on IPv6 but not IPv4 addresses. Does that make any sense?
UPDATE 2
I wasn't able to fix it, but pointing my domain name to ::1 instead of 127.0.0.1 in my /etc/hosts serves as a workaround for the time being.
UPDATE 3
8 months later I bumped into the same issue and found my own question here, still unanswered. But this time I can't apply the same workaround, because I need to bind the port forwarding to my IPv4 address so it can be accessed from other hosts.

Found the culprit: pfctl
AFAIK, pfctl is not supposed to run automatically but my /System/Library/LaunchDaemons/com.apple.pfctl.plist said otherwise.
The Packet Filtering was configured to redirect all incoming traffic on port 80 to 8080, and 443 to 8443. And this is done without any process actually listening to port 80 and 443, that's why lsof and netstat wouldn't show anything,.
/Library/LaunchDaemons/it.winged.httpdfwd.plist has the following
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>echo "rdr pass proto tcp from any to any port {80,8080} -> 127.0.0.1 port 8080" | pfctl -a "com.apple/260.HttpFwdFirewall" -Ef - && echo "rdr pass proto tcp from any to any port {443,8443} -> 127.0.0.1 port 8443" | pfctl -a "com.apple/261.HttpFwdFirewall" -Ef - && sysctl -w net.inet.ip.forwarding=1</string>
</array>
<key>RunAtLoad</key>
The solution was simply to listen on ports 8080 and 8443. All requests to ports 80 and 443 are now being redirected transparently.
While debugging this I found countless open questions about similar problems without answers. I hope this helps somebody.

Related

Pinging local host doesn't function

elasticsearch==7.10.0
I wish to ping local host '5601' to ensure kibana is running or not but apparently unable to ping.
Note: I am aware that elastic search has in-built function to ping but I still wish to ping using cmd line for a specific reason in my project.
C:\User>ping 5601
Pinging f00:b00:f00:b00 with 32 bytes of data:
PING: transmit failed. General failure.
PING: transmit failed. General failure.
PING: transmit failed. General failure.
PING: transmit failed. General failure.
Ping statistics for f00:b00:f00:b00:
Packets: Sent = 4, Received = 0, Lost = 4 (100% loss)
C:\User>ping http://localhost:5601
Ping request could not find host http://localhost:5601. Please check the name and try again.
Could someone help me?
You can use netstat to check if the port exposed by the Kibana UI, 5061 is in LISTEN mode
$ netstat -tlpn | grep 5601
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp6 0 0 :::5601 :::* LISTEN -
Or if you want to establish a connection to destination port 5601 you can use nc
$ nc -vz localhost 5601
Connection to localhost 5601 port [tcp/*] succeeded!

Bash ping server with addres and port and get short info

How I can connect to sever by ip and port, and get short info about it?
I tried to do it with netcat and curl, but info is too long. I also tried to use telnet but it is not a good way for me.
I have a script which connect to some addresses on specified ports and I if it is connected I want to show short info about it.
Is it possible? Is any other method to solve this problem?
IP addresses are different. They can be a http, mysql, ssl, etc.
I attach a code with a connection's function:
if nc -w 10 -z $1 $i; then
printf "\n$1:$i - Port is open\n\nSERVER INFO:\n";
printf "\n$(curl -IL $1)\n";
else
printf "\n$1:$i - Port is closed\n"
fi;
EDIT:
Example of response from server I would like to get
{IP number}: ssh - OpenSSH 6.0pl1, http - apache 1.3.67, https - httpd 2.0.57
You were pretty close. You can include the host just as you have in your script.
for port in $(seq 21 23); do
out=$(nc -w 1 -q 1 localhost $port)
echo port ${port}: $out
done
#port 21:
#port 22: SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7
#port 23:

execute shell script in ruby

I want to execute the following shell script
system('echo "
rdr pass on lo0 inet proto tcp from any to 192.168.99.1 port 80 -> 192.168.99.1 port 8080
rdr pass on lo0 inet proto tcp from any to 192.168.99.1 port 443 -> 192.168.99.1 port 4443
" | sudo pfctl -ef - > /dev/null 2>&1; echo "==> Fowarding Ports: 80 -> 8080, 443 -> 4443 & Enabling pf"'
)
This works fine, i now want to pass the IP address loaded from a YAML file, i tried the following
config.yaml
configs:
use: 'home'
office:
public_ip: '192.168.99.2'
home:
public_ip: '192.168.99.1'
Vagrantfile
require 'yaml'
current_dir = File.dirname(File.expand_path(__FILE__))
configs = YAML.load_file("#{current_dir}/config.yaml")
vagrant_config = configs['configs'][configs['configs']['use']]
system('echo "
rdr pass on lo0 inet proto tcp from any to '+vagrant_config['public_ip']+' port 80 -> '+vagrant_config['public_ip']+' port 8080
rdr pass on lo0 inet proto tcp from any to '+vagrant_config['public_ip']+' port 443 -> '+vagrant_config['public_ip']+' port 4443
" | sudo pfctl -ef - > /dev/null 2>&1; echo "==> Fowarding Ports: 80 -> 8080, 443 -> 4443 & Enabling pf"'
)
The second method does not work, nor it shows any error, can someone point me to the right direction, what i want is to read public_ip dynamically from config file or variable
Thanks
UPDATE 1
I get the following output
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.
No ALTQ support in kernel
ALTQ related functions disabled
pfctl: pf already enabled
What can be possibly wrong?
For troubleshooting purposes, it would be wise to output the command you're going to run prior to sending it out to system.
cmd = 'echo "
rdr pass on lo0 inet proto tcp from any to '+vagrant_config['public_ip']+' port 80 -> '+vagrant_config['public_ip']+' port 8080
rdr pass on lo0 inet proto tcp from any to '+vagrant_config['public_ip']+' port 443 -> '+vagrant_config['public_ip']+' port 4443
" | sudo pfctl -ef - > /dev/null 2>&1; echo "==> Fowarding Ports: 80 -> 8080, 443 -> 4443 & Enabling pf"'
puts "Command to run:\n\n#{cmd}"
system( cmd )
Then, it would be wise to make the output from the system command visible. To make sure you get this feedback, I suggest you replace
sudo pfctl -ef - > /dev/null 2>&1
with (adding '-v' for more verbose output - pfctl man page)
sudo pfctl -efv -
and then look for the output and/or error messages.
Then, once the bugs are sorted out, you can put it back into stealthy, quiet mode :D
Also, since you are running with sudo you'll need to make sure the shell you're running within has sudo privileges and also make sure you're not being prompted for a password unknowingly.

(OS X) Port in use, however it is not shown by netstat or lsof

Sorry for my english.
I was trying to forward port 80 from my vagrant box to host machine (OS X) and got this message
"The forwarded port to 80 is already in use on the host machine."
So, in order to figure out which program uses port 80 i ran this:
➜ ~ sudo lsof -n -i:80 | grep LISTEN
➜ ~
However, as you can see, it shows nothing.I have also tried netstat, but result was the same. Then i tried to use netcat + tcpdump to look at tcp session:
➜ ~ nc -vvv 127.0.0.1 80
Connection to 127.0.0.1 80 port [tcp/http] succeeded!
➜ ~
In another window:
➜ ~ sudo tcpdump -ni lo0 port 80
Password:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo0, link-type NULL (BSD loopback), capture size 65535 bytes
00:03:47.019805 IP 127.0.0.1.50666 > 127.0.0.1.80: Flags [S], seq 2187569264, win 65535, options [mss 16344,nop,wscale 4,nop,nop,TS val 194193524 ecr 0,sackOK,eol], length 0
00:03:47.019834 IP 127.0.0.1.80 > 127.0.0.1.50666: Flags [R.], seq 0, ack 2187569265, win 0, length 0
So it looks like the port is closed, because it immediately sent RESET flag, but why did nc show that connection was successful and lsof show nothing.
I'm really confused. Can anyone tell me what is going on, or what am i doing wrong?
I can provide additional information if needed.
Thanks!
Looks like that's firewall reset connection.
Turn off Avast WebShield if it exists.

Curl: Bypass proxy for localhost

I'm under a proxy, and if I try curl http://localhost/mysite or curl http://127.0.0.1/mysite curl try to resolve it with the proxy. So I tried with --noproxy option, but doesn't work. Is working ok for external servers with the proxy as curl http://mysite.com.
My configuration:
Cygwin (bash) under Windows 8 with curl extension.
Proxy: proxy.domain.xx:1080 without authentication
http_proxy=http://proxy.domain.xx:1080
Local Server: XAMP Version 1.8.0
Apache ports: 80,443
Browser: Chrome with proxy, but configured to access to localhost and *.dev
From the curl --help
--noproxy : Comma-separated list of hosts which do not use proxy
What I tried:
I have deactivated the firewall and nothing
$ curl -v http://localhost/mysite -> Debug:
Response
Connected to proxy.domain.xx (200.55.xxx.xx) port 1080 (#0)
GET http://localhost/mysite HTTP/1.1
User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
Host: localhost
Accept: */*
Proxy-Connection: Keep-Alive
The system returned: <PRE><I>(111) Connection refused</I></PRE>
curl -v --noproxy localhost, http://localhost/muestra
Response
About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /mysite HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: localhost
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: Apache/2.4.2 (Win32) OpenSSL/1.0.1c PHP/5.4.4
< Location: http://localhost/mysite
< Content-Length: 331
< Content-Type: text/html; charset=iso-8859-1
Any idea how to fix this?
After
curl -v --noproxy localhost, http://localhost/muestra
curl responded with
About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
So it clearly stated that it connected to localhost.
try below, to bypass proxy service for local ips
export no_proxy=localhost,127.0.0.1
use
curl -v --noproxy '*' http://abc.com
to completely disable proxy.
or if you want to disable proxy for only abc.com destination
curl -v --noproxy "abc.com" http://abc.com
where abc.com is the url you want to go
As some others said, the --noproxy options is what you are looking for.
https://curl.haxx.se/docs/manpage.html#--noproxy
Apparently, the second request you tried was receiving a HTTP 301 response, so you probably also want to use the -L option to follow redirects:
https://curl.haxx.se/docs/manpage.html#-L
You can alias curl to always ignore proxies for localhost requests.
alias curl='curl --noproxy localhost,127.0.0.1'
Add it to your .bashrc file for convenience:
echo "alias curl='curl --noproxy localhost,127.0.0.1'" >> ~/.bashrc
In Windows, the following option worked for me for connecting to localhost.
curl --proxy "" --location http://127.0.0.1:8983
Curl expects the port to be specified with proxy this solution worked for me
export http_proxy="http://myproxy:80"
As a workaround, you can just unset the variable http_proxy before running your curl without the option --noproxy.

Resources