I have a little problem. I've tried to secure my MongoDB in docker container (btw I'm using docker-compose) by restricting access from outside of the docker network. I've just simply removed ports from docker-compose mongo services and it worked, I could not access it from outside. But is that enough? And is it the right decision? Maybe someone has another solution.
Here are a few best practices you can follow from the security point of view:
Prefer Minimal Base Image: The base image you select can also have vulnerabilities, you can look for security vulnerabilities before selecting the base image. Select the minimal base image as it may ensure that there are fewer vulnerabilities.
Least Privileged User: If no user is specified in the Dockerfile, by default the container is run using root privilege. To restrict access, create a dedicated user and user group in the docker image.
Sign and Verify the images: We run the docker images in our production environment, thus it is quite important to authenticate the docker image before using it. You should sign your docker image and before running you should also verify it.
Use Security Softwares and linters: Use security software to scan your docker images for any vulnerabilities, you can also use a linter which statically analyzes your Dockerfile and gives a warning when there is a security vulnerability.
Don’t leak sensitive information to Docker images: The secrets must be kept outside of the Dockerfile. If you copy the secret, then they get cached on the intermediate docker container, to avoid this problem, you can use multi-stage build or docker secret commands.
Credits: Thanks to Liran Tal and Omer Levi Hevroni for the blog. I learned these best practices from their blog, please visit this blog for more details and a few more best practices.
Related
We've created a new AppService and successfully deployed our solution backend through docker-compose (preview), but when we update one (or more) image on the registry and we restart the appservice to get docker-compose to get the new version, we get errors of ambiguous network name like this one
InnerException: Docker.DotNet.DockerApiException, Docker API responded with status code=BadRequest, response={"message":"network my_app_service_multi_nw__0 is ambiguous (94 matches found on name)"}
In our docker-compose.yml we don't have any network name specified (since network is a not-supported option)
At the moment, the only solution we found is to delete entirely the appservice and create a new one (WITH A DIFFERENT NAME, also)
What we're doing wrong? Is it possible to prune all unused networks?
We've contacted Microsoft for support, they've told us that it's a known bug and a temporary fix could be changing App Service plan.
Apparently, changing from S1 to B1 fixed the issue for us.
The answer from #Doc is currently not working for us, as scaling up or down the plan does not seem to reset the underling VM. We can't delete the app or change the name, therefore we are currently stuck with this issue...
EDIT: It was not sufficient to change from B2 to S2, but changing from B2 to P1V2 fixed the issue. A hint should be that, when you change the plan, you should see a message at the bottom "Outgoing IP addresses for your app might change", which ensures that your App Service app is actually migrating to a different VM, therefore resetting the Docker configuration.
I got the same issue in local when try to run with Visual Studio and got fixed with following steps.
step 1: List existing networks
docker network ls
Find duplicate network names
Step 2: Remove one network
docker network rm <NETWORK ID>
I am trying to configure or setup the production environment of whatsapp business api as mentioned in the link https://developers.facebook.com/docs/whatsapp/installation/prod-single-instance
I have done everything mentioned in this my dockers are also running on port:9090 as can be seen in the image
still I can't access it. Whenever I try to call https://localhost:9090 the error with "This site can’t be reached" occurs. Whatsapp business api does not have good documentation or tutorials till now. So this site is the only last way for me.
I had a similar problem which could be your case, I saw the docker containers OK but nothing was working. After a day searching I saw where it happened, my problem was I installed mysql MANUALLY (not docker container) in the same instance where docker is running and in db.env I just used 127.0.0.1, this was passed literally to docker container, then looking at a the wait_on_mysql.sh script, the whastapp docker containers were waiting util the mysql ip has conectivity to actually do something and was printing "MySQL is not up yet - sleeping" each second, of course they wouldn't find any conectivity.
Since my instalation is for development, and I am already using such database to other stuff, my solution was to use the 172.17.0.1(docker gateway of the containers) IP instead, then add two sets of network iptables rules to the host to redirect from the docker containers IP to the IP binded by mysql when using such port (3306, the default in my case). After that everything works well. I think there are better solutions, but I didn't want to go far on it, you should evaluate you case if apply.
check the command:
docker-compose logs > debug_output.txt
That gives you insight about whats happening, hope it can helps someone.
I think your setup is already complete. You just need to start with the registration process and start sending messages. The containers are up and running but calling https://localhost:9090 won't send you any response as this is not any specified API endpoint expected to be used.
Since you're using prod single instance, the documentation can be found here which seems pretty straight forward. https://developers.facebook.com/docs/whatsapp/installation/prod-single-instance
You seem to have completed till the 7 steps. The next step can be to perform a health check to make sure it is healthy. The API endpoint for that would be https://localhost:9090/v1/health https://developers.facebook.com/docs/whatsapp/api/health
Has your db also been setup?
I cannot see it in the docker screenshot.
Also - you have to accept the certificate, as it does not have a public CA issues certificate.
I'm developing a platform that monitor emails, save the results in a Mongo database (through Parse-Server) and display the results on a web app (using AngularJS).
Basically, for each customer i want a SMTP server, a Parse Server, a MongoDB & a web platform.
I thought of using Docker for more scalability and the idea is to automatically create the containers when the user signup on my website but I don't really understand how to link these containers together : web1|smtp1 connected to parse1 connected to mongo1 & web2|smtp2 connected to parse2 connected to mongo2.
In the end, i want the customers to access the web app through web1.website.com, so I think i should also use Haproxy..
I'm just wondering if it's really the best way to do it as i'm going crazy with the automation process and if you have any tips to do that.
Using Docker (specifically Docker Compose) linking containers together is very easy. In fact it happens out of the box! If you compose all your containers at the same time, a Docker network is created for your "composed app" and all containers can see each other.
See the documentation here.
Each container can now look up the hostname web or db and get back the appropriate container’s IP address. For example, web’s application code could connect to the URL postgres://db:5432 and start using the Postgres database.
Installed this (https://github.com/BanzaiMan/openshift-origin-cartridge-phppgadmin) to my Tiny Tiny RSS application on OpenShift to manage my database.* However, after the installation and a few restarts, .../phppgadmin/ URL gives me 404 error. Any ideas? Could it be the github cartridge is using old environmental variables? Thanks!
*The reason I want to install phppgadmin in the first place is to vacuum my ever-expanding database on Tiny Tiny RSS application. vacuumdb and vacuumdb -f -a only claim ~50mb and app-tidy does ~100mb, as opposed to ~600mb previously. So, I need to find another solution, like phppgadmin, to address my quota limitations.
Instead of using phppgadmin, it would be a much better idea to download pgadmin onto your computer and then use the rhc port-forward command to connect to your database and do your maintenance. That cartridge is pretty old and likely will not get updated anytime soon (or ever).
We are dockerizing an application (written in Node.js) that will need to access some sensitive data at run-time (API tokens for different services) and I can't find any recommended approach to deal with that.
Some information:
The sensitive information is not in our codebase, but it's kept on another repository in encrypted format.
On our current deployment, without Docker, we update the codebase with git, and then we manually copy the sensitive information via SSH.
The docker images will be stored in a private, self-hosted registry
I can think of some different approaches, but all of them have some drawbacks:
Include the sensitive information in the Docker images at build time. This is certainly the easiest one; however, it makes them available to anyone with access to the image (I don't know if we should trust the registry that much).
Like 1, but having the credentials in a data-only image.
Create a volume in the image that links to a directory in the host system, and manually copy the credentials over SSH like we're doing right now. This is very convenient too, but then we can't spin up new servers easily (maybe we could use something like etcd to synchronize them?)
Pass the information as environment variables. However, we have 5 different pairs of API credentials right now, which makes this a bit inconvenient. Most importantly, however, we would need to keep another copy of the sensitive information in the configuration scripts (the commands that will be executed to run Docker images), and this can easily create problems (e.g. credentials accidentally included in git, etc).
PS: I've done some research but couldn't find anything similar to my problem. Other questions (like this one) were about sensitive information needed at build-time; in our case, we need the information at run-time
I've used your options 3 and 4 to solve this in the past. To rephrase/elaborate:
Create a volume in the image that links to a directory in the host system, and manually copy the credentials over SSH like we're doing right now.
I use config management (Chef or Ansible) to set up the credentials on the host. If the app takes a config file needing API tokens or database credentials, I use config management to create that file from a template. Chef can read the credentials from encrypted data bag or attributes, set up the files on the host, then start the container with a volume just like you describe.
Note that in the container you may need a wrapper to run the app. The wrapper copies the config file from whatever the volume is mounted to wherever the application expects it, then starts the app.
Pass the information as environment variables. However, we have 5 different pairs of API credentials right now, which makes this a bit inconvenient. Most importantly, however, we would need to keep another copy of the sensitive information in the configuration scripts (the commands that will be executed to run Docker images), and this can easily create problems (e.g. credentials accidentally included in git, etc).
Yes, it's cumbersome to pass a bunch of env variables using -e key=value syntax, but this is how I prefer to do it. Remember the variables are still exposed to anyone with access to the Docker daemon. If your docker run command is composed programmatically it's easier.
If not, use the --env-file flag as discussed here in the Docker docs. You create a file with key=value pairs, then run a container using that file.
$ cat >> myenv << END
FOO=BAR
BAR=BAZ
END
$ docker run --env-file myenv
That myenv file can be created using chef/config management as described above.
If you're hosting on AWS you can leverage KMS here. Keep either the env file or the config file (that is passed to the container in a volume) encrypted via KMS. In the container, use a wrapper script to call out to KMS, decrypt the file, move it in to place and start the app. This way the config data is not exposed on disk.