Spring Boot, Debian, Embedded Tomcat close external port - spring-boot

This is my Spring Boot application properties:
server.port: 8081
On Debian 9 I run Spring Boot war with Embedded Tomcat in the following way:
java -Dfile.encoding=UTF-8 -jar api-0.0.1.war
Right after that, I can access the application by the following url:
http://localhost:8081/api/v1.0
I'd like to close external access to 8081 port and leave only access to this port from the internal system.
I order to achieve this, I applied the following rule:
/sbin/iptables -A INPUT -p tcp --destination-port 8081 -j DROP
/sbin/service iptables save
but right now I'm unable to access url http://localhost:8081/api/v1.0 from another application on the same machine.
What am I doing wrong and how to fix it?

You need to allow the localhost post.
iptables -A INPUT -p tcp -s localhost --destination-port 8081 -j ACCEPT

Related

Tomcat on port 8080 failed using Spring boot Java

i am beginner of spring boot. when i run the spring boot application i ran into the problem with The Tomcat connector configured to listen on port 8080 failed to start. Spring boot
i don't how to solve the problem. i have install mysql when i ran the mysql it port also 8080. so how to sort out the problm.
***************************
APPLICATION FAILED TO START
***************************
Description:
The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured.
Action:
Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port.
Seems like 8080 port is already used by some other process.
Change the port of spring-boot tomcat port by adding the server.port=8090 in application.properties.
Change 8090 to any port you want to use.
Your 8080 port is already used by some other process.
Change the port of spring-boot server.port=8090 in application.properties.
You can change your application run server port any port number to if that port number would not belong to any other process on your computer.
and another thing if you use IntelliJ idea to develop, accidentally close your IDE without proper way this error may have occurred {personal experience}.
It is not necessarily required to change the port, you can just end the process of it to release it in your spring application
Open cmd as administrator and enter the following commands:
netstat -year | findstr 9330
Once you find the process number, type it in the highlight of the following command:
taskkill /F /PID <Process ID>
The result should appear as follows:
SUCCESS: The process with PID < Process Id > has ended.

Cannot connect to Container-optimized-os (running a spring-boot application using docker) using external ip

I have created a Google compute instance with Container-optimized-OS image.
I have configured the firewall to allow http and https.
I am using the docker image with spring boot application which connects to cloudsql. When I use run command on compute engine instance ssh, i.e. (docker run --rm name), the spring boot app is started successfully.
When I try to access the webservices through compute engine instance external ip, it is not working.
I went through a different question, and found that I should try using the sudo wget http://localhost command on the instance cli first and if it is good then everything should be good. But I am getting a connection refused message on 127.0.0.1:80.
I also tried the command to open port from Container optimized OS, I.E.
sudo iptables -w -A INPUT -p tcp --dport 80 -j ACCEPT , nothing is working.
The default port for Spring Boot is 8080 and not 80.
Run this command inside the instance container to see what ports are in LISTENING state:
sudo netstat -tulpn | grep LISTEN
You can redirect port 80 to port 8080 with this command:
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
Note: This iptables command only redirects port 80 to 8080 on network interfaces. This has no effect for localhost or 127.0.0.1.
For Google Compute Engine instances you do not need to enable ports using iptables. This is done via Google VPC firewall rules. You can use both but make sure you understand exactly what you are configuring and the side effects.
Note: Your Spring Boot application needs to listen on 0.0.0.0 and not 127.0.0.1 nor localhost. The last two are internal only addresses. 0.0.0.0 means listen on all network interfaces.
Note: Do not use sudo in front of wget. This is not necessary.
First, confirm what port your springboot application uses - if it's 8080 or 80. This depends on what you have configured inside application.properties file. This port is referred to as ContainerPort in below steps.
Execute docker run <image-name>:<tag>. This will run the image and show container logs on the console. If there is something wrong with your spring-boot app, the logs will show that and the container will shutdown. Press Ctrl+C to stop the container and return to shell.
If there is no error in step 1 run docker run -d -p<HostPort>:<ContainerPort> <image-name>:<tag>. Here HostPort is any free port in your GCP host VM and ContainerPort is the port used by your spring boot application within the container. Option d starts your container in detached mode.
Run docker ps and make sure that the container started in step 2 is running. It may not run if there is an error - for example if the HostPort you specified is already in use.
If step 3 shows that the container is running, execute curl http://localhost:<HostPort>/<End-Point-Path>. Here End-Point-Path is a valid path to a working endpoint within the container. If the endpoint is correct you should see expected result from the spring-boot app in the console.
Navigate to Google Cloud Console -> VPC network -> Firewall rules and add a firewall rule to open HostPort on your GCP VM.
Access your endpoint via the VM's external IP with URL - http://<VM-External-IP>:<HostPort>/<End-Point-Path>
Unless there is an application issue with your spring-boot app these steps should get you going.
I was able to build the correct solution by your help (John Hanley and Cyac).
I am combining both solutions in order to help the next person facing this.
As told by John, by default Spring boot uses port 8080, not 80 and as specified by Cyac you need to specify the port as 80 explicitly in application.properties file using
server.port=80
Make sure you expose the port 80 in docker image
On GCP Contaier optimized OS make sure you have allowed traffic for HTTP and HTTPs
Run command:
sudo iptables -w -A INPUT -p tcp --dport 80 -j ACCEPT
Run docker using:
docker run -p 80:80 SPRING_IMAGE.
Where SPRING_IMAGE is the name of the docker image with spring boot build.
Test by using curl http://localhost/ENDPOINT_NAME , e.g. http://localhost/shops/all

Localhost vs 0.0.0.0 with Docker on Mac OS

I am reading the docs here and I find myself a bit confused, since running
docker run --name some-mysql -p 3306:3306 -d mysql
or
docker run --name some-mysql -p 127.0.0.1:3306:3306 -d mysql
then mysql --host localhost --port 3306 -u root gives me the following error :
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2).
But running mysql -u root -p --host 0.0.0.0 works.
Does someone have an explanation ?
With docker port forwarding, there are two network namespaces you need to keep track of. The first is inside your container. If you listen on localhost inside the container, nothing outside the container can connect to your application. That includes blocking port forwarding from the docker host and container-to-container networking. So unless your container is talking to itself, you always listen on 0.0.0.0 with the application you are running inside the container.
The second network namespace is on your docker host. When you forward a port with docker run -p 127.0.0.1:1234:5678 ... that configures a listener on the docker host interface 127.0.0.1 port 1234, and forwards it to the container namespace port 5678 (that container must be listening on 0.0.0.0). If you leave off the ip, docker will publish the port on all interfaces on the host.
So when you configure mysql to listen on 127.0.0.1, there's no way to reach it from outside of the container's networking namespace. If you need to prevent others outside of your docker host from reaching the port, configure that restriction when publishing the port on the docker run cli.
As described in the mysql documentation (https://dev.mysql.com/doc/refman/5.7/en/connecting.html), when you connect to 127.0.0.1 with the client, it'll try to use the unix sockets to perform this operation. Normally this would work fine since it's on the same host. In Docker the socket file is not available.

How to enable port 80 or 443 for Spring Boot app deployed with BoxFuse

Spring Boot app is configured (default) to run Tomcat on port 8080. This application gets deployed on AWS via BoxFuse tool and exposed at port 8080 (as expected/configured).
I have tried setting server port to 80 in boot application properties but it causes permission denied issue and the solution seems to be modifying iptables or reverse proxy. ipTables modification is not possible due to boxFuse image/env not being editable.
Question: Is there a way in BoxFuse to setup the spring boot application on port 80 without actually setting up another instance for reverse proxy? It is an overhead to setup an instance just for port correction since can't change the iptables.
Also, Is it possible that this application is run with root privileges on the AWS instance so that I do not need to modify iptables or set up reverse proxy?
There is a -ports.Name option available when deploying the application with BoxFuse.
Docs: https://cloudcaptain.sh/docs/gradle/run
Example:
boxfuse -ports.http=80 -env=test run myapprepo/myapp:0.1
Verified on local dev environment. For Mac, it should be run as a privileged command via sudo
sudo boxfuse -ports.http=80 run myapprepo/myapp:0.1
To add, works for 443 too.

Docker tomcat7 container cannot connect to host activemq

I am admittedly relatively new to using Docker for environment isolation, but I've run into a problem I am yet to solve, and I'm looking for some advice on how to proceed. Apologies if this is dirt simple.
I have an image built with this Dockerfile:
FROM java:7-jre
MAINTAINER me <email redacted>
ENV CATALINA_HOME="/usr/local/tomcat"
ENV PATH=$CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
#Add tomcat tarball with configs
#need to figure out if war files should be auto-deploy or manual-deploy via manager
ADD ./ $CATALINA_HOME
WORKDIR $CATALINA_HOME
RUN tar -xmvf tomcat.tar.gz --strip-components=1 \
&& rm bin/*.bat \
&& rm tomcat.tar.gz*
EXPOSE 8080
#quite possibly unnecessary to expose 61616
EXPOSE 61616
CMD catalina.sh run
Because my host is Mac OSX, I'm using the boot2docker package. The port forwarding is a real PITA, but for now I'm just binding host 8080 to container 8080 when I run the container (-p 8080:8080) and I have 8080 forwarded in the boot2docker networking setup.
This image runs a container just fine, and I am able to manually upload and deploy .war files to this container while it's running.
On my local machine, I am running ActiveMQ. Eventually I'll put this in a container but I need to get past this hurdle first. ActiveMQ is running with the default port 61616 listening, as shown in this netstat output:
14:14 $ netstat -a | grep 6161
tcp46 0 0 *.61616 *.* LISTEN
The problem I'm having is that deployed war files in my tomcat container are unable to talk to the physical host on 61616. Here is the actual error from the catalina.out log on the container (I added some line breaks to make it easier to read):
Could not refresh JMS Connection for destination 'request' - retrying in 5000 ms.
Cause: Error while attempting to add new Connection to the pool; nested exception is javax.jms.JMSException:
Could not connect to broker URL: tcp://localhost:61616.
Reason: java.net.ConnectException: Connection refused
Admittedly, I think it's because the war file is configured to use localhost:61616 to connect to AMQ -- it doesn't feel right for localhost inside the container to "work" reaching back to the host. I'm not sure what variable value I should set that to, or if that's even the actual issue. I would think that if it's a dynamically-allocated black-magic IP address, it'd be relatively painful to keep reconfiguring inside war files.
Corollary: are there other considerations I would need to make beyond this configuration if I wanted to link this tomcat container with an AMQ one?
Thanks in advance for your attention. ~P
First, you shouldn't need to EXPOSE 61616 on the container. (That would allow the container to listen on port 61616, which is not what you want.)
What you do need though is to access docker's localhost (your boot2docker VM) from within the docker container. The best way I've found to do this, so far, from this answer, is to run inside your docker container:
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
That is going to give you the IP address of your boot2docker VM, as seen from within the current docker container. I'll leave it up to you to figure out how to configure your JMS client to connect to that IP address, but one idea that comes to mind is something like:
echo $DOCKER_HOST_IP my-jms-hostname >> /etc/hosts
And then you can hardcode your JMS configuration to hit my-jms-hostname:61616
I recommend that you put the above two commands into a start script that you use to startup your application server in the container.
Next, you will need to find a way to tunnel that port on your boot2docker VM to your local host OS. For example, on your local host OS, run
boot2docker ssh -R61616:localhost:61616
That will listen on the remote (boot2docker VM's) port 61616 and forward it to your local host OS's localhost:61616, which is where ActiveMQ is hopefully listening happily for an incoming connection from your application server's JMS client.

Resources