#iptables-persistent
Explore tagged Tumblr posts
elwonplacenta · 10 days ago
Text
Stepping into the Portal: Building a Captive Wi-Fi Experience on our Raspberry Pi
Today's adventure in our Raspberry Pi networking project took a fascinating turn! Having successfully established our Pi as an internet-sharing router via Ethernet, we set our sights on a more sophisticated user experience: implementing a captive portal.
For those unfamiliar, a captive portal is the web page that pops up when you connect to a public Wi-Fi network, often requiring you to agree to terms of service or log in before you can access the internet. This is exactly what we aimed to create for our little network managed by the Raspberry Pi.
Laying the Foundation: Installing a Web Server
Our first step was to install a web server on the Raspberry Pi. We opted for Nginx, a lightweight and powerful choice that's perfect for this task. With a few simple commands in the terminal (sudo apt update and sudo apt install nginx), our web server was up and running. We even verified its status to ensure everything was as it should be.
To make sure our captive portal page would be accessible, we also opened up the necessary ports (HTTP on port 80 and HTTPS on port 443) in the Raspberry Pi's firewall using iptables. We made sure to save these new rules so they persist across reboots.
Crafting the Welcome Mat: Creating the Portal Web Page
Next, we rolled up our sleeves and created a basic HTML page to serve as our captive portal. We replaced the default Nginx welcome page with our own index.html. This simple page includes a welcome message, a (very basic for now!) terms of service agreement, and a button that users will eventually click to gain internet access.
We even added a little bit of basic CSS to make it look presentable. The idea is to have a clear and concise page that informs users and gets their agreement before they hop online.
What's Next? The Magic of Redirection
With the web server in place and our initial captive portal page ready, the next stages will involve the more intricate parts of making the portal truly functional. We'll be diving into:
* DNS Interception: Configuring dnsmasq to redirect all DNS requests from unconnected clients to the Raspberry Pi's IP address.
* HTTP/HTTPS Redirection with iptables: Setting up rules to intercept all web traffic from unauthorized users and force it to our captive portal page.
* The "Agreement" Mechanism: Developing the backend logic (likely a simple script for now) that gets triggered when a user clicks "I Agree," and then modifies the firewall to grant that user internet access.
Today was all about laying the groundwork – installing the necessary tools and creating the content for our captive portal. It's exciting to see the project evolving from basic internet sharing to a more controlled and user-aware network. Stay tuned for the next steps as we delve into the redirection magic!
0 notes
nixcraft · 2 years ago
Text
-> How to save iptables firewall rules permanently on Linux
8 notes · View notes
timothemauzet · 8 years ago
Photo
Tumblr media
Iptables est une interface qui permet de configurer le firewall interne de votre Debian. Celui-ci permet de protéger votre serveur de plusieurs type d'attaque.
0 notes
computingpostcom · 3 years ago
Text
Due to the increasing complexity of applications in infrastructure, many system admins and developers find it hard to manage the environments which may require a lot of resources and hence expensive. One solution to this challenge was the introduction of a virtualization technique known as containerization. This technology has been highly adopted in the past decade with tools such as Kubernetes, Podman, and Docker playing a significant part. Containerization is the packaging of a portable computing environment that contains everything an application needs to run, from binaries to dependencies. With this technology, virtualization occurs at the host level. This requires no virtual hardware, operating system, or virtual kernel. Podman is a containerization tool developed by RedHat to act as a drop-in replacement for Docker. This daemon-less container engine can be used to develop, manage and run OCI(Open Container Initiative) containers. It can also be used to pull container images and configure containers to run automatically on boot just like Docker. Podman is highly preferred due to the following: No daemon required: this allows for a faster startup and fewer resource requirements Compatibility with Docker, it is possible to pull images from Docker Hub or Quay.io Native systemd integration: you can create systemd unit files and run containers as system services Run containers in rootless mode: this makes it easy to run containers securely without any additional privileges Podman closely works with other tools in container management. These tools include: Skopeo: for sharing/finding container images on Docker registries, the Atomic registry, private registries, local directories, and local OCI-layout directories. Buildah: is used to facilitate the building of OCI images either from scratch or using an image as a starting point. In this guide, we will install Podman 4 on Debian 11 / Debian 10 and also use it to pull images and run containers. Step 1. Install the Required Tools Podman can be installed from the Podman repositories but the available version is Podman 3. To install Podman 4, we need to build it from a source code. Before we begin, ensure your system and the available packages are updated to the latest versions. sudo apt update && sudo apt upgrade -y You also need to install the required tools to build Podman from the source code: sudo apt install btrfs-progs git iptables libassuan-dev libbtrfs-dev libc6-dev libdevmapper-dev libglib2.0-dev libgpgme-dev libgpg-error-dev libprotobuf-dev libprotobuf-c-dev libseccomp-dev libselinux1-dev libsystemd-dev pkg-config runc uidmap make curl vim gcc -y Step 2. Install Golang To build Podman from the source code, you need Golang 1.16 and higher. This version can be installed by downloading the latest binary from the Golang release page. Alternatively, pull the file with the command: sudo -i wget https://storage.googleapis.com/golang/getgo/installer_linux Make the script executabled chmod +x ./installer_linux Now run the installer to download the latest release of Golang: ./installer_linux Persist the new environment variables to your current session: source ~/.bash_profile Verify the installation. # go version go version go1.19.1 linux/amd64 Step 3. Install runc and Conmon The Conmon module is used to monitor OCI Runtimes. It can be installed with the commands: cd ~ git clone https://github.com/containers/conmon cd conmon export GOCACHE="$(mktemp -d)" make sudo make podman cd .. Once installed, proceed and install runc which is picked as the default runtime by Podman. git clone https://github.com/opencontainers/runc.git $GOPATH/src/github.com/opencontainers/runc cd $GOPATH/src/github.com/opencontainers/runc make BUILDTAGS="selinux seccomp" cp runc /usr/bin/runc cd ~/ Verify your installation: # runc --version runc version 1.1.0+dev commit: v1.1.0-272-g4a51b047 spec: 1.0.2-dev go: go1.19 libseccomp: 2.5.1
Step 4 – Configure CNI networking plugins Create a directory to store the CNI networking plugins at /etc/containers sudo mkdir -p /etc/containers Download the config file into the directory. sudo curl -L -o /etc/containers/registries.conf https://src.fedoraproject.org/rpms/containers-common/raw/main/f/registries.conf sudo curl -L -o /etc/containers/policy.json https://src.fedoraproject.org/rpms/containers-common/raw/main/f/default-policy.json Install additional packages on Debian 11 / Debian 10 sudo apt install -y libapparmor-dev libsystemd-dev Step 5 – Install Podman 4 on Debian 11 / Debian 10 Once all the above configurations have been made, download the latest Podman source code. This can be accomplished by visiting the GitHub release page It is also possible to download the file with the commands: sudo apt install curl wget -y TAG=$(curl -s https://api.github.com/repos/containers/podman/releases/latest|grep tag_name|cut -d '"' -f 4) rm -rf podman* wget https://github.com/containers/podman/archive/refs/tags/$TAG.tar.gz Extract the downloaded file: tar xvf $TAG.tar.gz Now build and install Podman 4 from the source code using the commands: cd podman*/ make BUILDTAGS="selinux seccomp" make install PREFIX=/usr Once complete, verify the installation: $ podman version Client: Podman Engine Version: 4.2.1 API Version: 4.2.1 Go Version: go1.19.1 Built: Fri Sep 23 13:38:07 2022 OS/Arch: linux/amd64 To be able to configure network namespaces, you need to install the slirp4netns package. Download the latest release file from the GitHub Release. Alternatively, use cURL as shown cd ~/ TAG=$( curl -s https://api.github.com/repos/rootless-containers/slirp4netns/releases/latest|grep tag_name|cut -d '"' -f 4) curl -o slirp4netns --fail -L https://github.com/rootless-containers/slirp4netns/releases/download/$TAG/slirp4netns-$(uname -m) Make the file executable: chmod +x slirp4netns Copy the binary file to your $PATH: sudo cp slirp4netns /usr/local/bin Step 6 – Use Podman 4 on Debian 11 / Debian 10 Now you can use Podman to build and pull images, spin containers and manage them easily. Manage Container Images To pull an image, use the command with the syntax: podman pull For example, to pull an Nginx image from docker hub, the command will be: $ podman pull docker.io/library/nginx:latest Trying to pull docker.io/library/nginx:latest... Getting image source signatures Copying blob 7247f6e5c182 done Copying blob 7247f6e5c182 done Copying blob 7a6db449b51b done Copying blob ca1981974b58 done Copying blob d4019c921e20 done Copying blob 7cb804d746d4 done Copying blob e7a561826262 done Copying config 2b7d6430f7 done Writing manifest to image destination Storing signatures 2b7d6430f78d432f89109b29d88d4c36c868cdbf15dc31d2132ceaa02b993763 Once pulled, you can view the images with the command: $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/library/nginx latest 2b7d6430f78d 8 days ago 146 MB docker.io/library/alpine latest 9c6f07244728 3 weeks ago 5.83 MB docker.io/library/ubuntu latest df5de72bdb3b 4 weeks ago 80.4 MB You can delete a container image, say ubuntu:latest from docker hub with the command: $ podman rmi docker.io/library/ubuntu:latest Untagged: docker.io/library/ubuntu:latest Deleted: df5de72bdb3b711aba4eca685b1f42c722cc8a1837ed3fbd548a9282af2d836d Before you delete an image, you need to ensure the container using it is stopped and deleted. Build Container Images It is also possible to build your win container images. The images can be used locally or uploaded to a registry. To create a container image on Podman, you need to create a Dockerfile. vim Dockerfile In the file, you need to add the commands to be executed. For example: FROM ubuntu:20.04 RUN apt-get up date -y ENV DEBIAN_FRONTEND=noninteractive RUN apt-get install -y gnupg apt-transport-https apt-utils wget
RUN echo "deb https://notesalexp.org/tesseract-ocr5/focal/ focal main" \ |tee /etc/apt/sources.list.d/notesalexp.list > /dev/null RUN wget -O - https://notesalexp.org/debian/alexp_key.asc | apt-key add - RUN apt-get update -y RUN apt-get install tesseract-ocr -y RUN apt install imagemagick -y ENTRYPOINT ["tesseract"] RUN tesseract -v Now build a container image with the command: podman build . -t tesseract:latest The build image will have the name tesseract and tagged as latest. Once complete, check if the image is available: $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/tesseract latest a98239ee7925 About a minute ago 313 MB docker.io/library/nginx latest 2b7d6430f78d 8 days ago 146 MB docker.io/library/alpine latest 9c6f07244728 3 weeks ago 5.83 MB docker.io/library/ubuntu 20.04 3bc6e9f30f51 4 weeks ago 75.2 MB Manage Containers Containers can be run from existing images or by downloading images from the preferred registry. For example, to run a container from the created Tesseract images, issue the command: $ podman run tesseract:latest -v tesseract 5.2.0 leptonica-1.79.0 libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 2.0.3) : libpng 1.6.37 : libtiff 4.1.0 : zlib 1.2.11 : libwebp 0.6.1 : libopenjp2 2.3.1 Found OpenMP 201511 Found libarchive 3.4.0 zlib/1.2.11 liblzma/5.2.4 bz2lib/1.0.8 liblz4/1.9.2 libzstd/1.4.4 Found libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3 You can also run a container using an image available in the registry. podman run docker.io/library/hello-world Sample output: To check if the container is running, use the command: podman ps To list all the containers including the ones not running, issue the command: $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bff200dbe9b8 localhost/tesseract:latest -v 5 minutes ago Exited (0) 5 minutes ago gallant_mahavira 34c490d56716 docker.io/library/nginx:latest nginx -g daemon o... 5 minutes ago Created 0.0.0.0:80->80/tcp mynginx1 26f64c70d1df docker.io/library/nginx:latest nginx -g daemon o... 3 minutes ago Exited (0) About a minute ago mynginx a51d55a7d880 docker.io/library/hello-world:latest /hello 52 seconds ago Exited (0) 52 seconds ago romantic_jang To stop a container, run the command: podman stop container_name/container_ID To remove a container, first, stop it, then execute the command: podman rm container_name/container_ID That marks the end of this guide on how to install Podman 4 on Debian 11 / Debian 10. Now you are set to pull images and run containers as desired.
0 notes
ubuntu-server · 4 years ago
Text
Save iptables rules over reboots on Ubuntu 16 and Ubuntu 18 – persistent iptables rules
Save iptables rules over reboots on Ubuntu 16 and Ubuntu 18 – persistent iptables rules
Moving towards the firewalld software and especially the systemd some good old init scripts got missing! For example, one of those good scripts is the init script for iptables firewall, which allows saving iptables rules and during boot, it loads them again. With the init iptables script we have persistence of the iptables rules. Meanwhile, we can always call the init script with “save” argument…
View On WordPress
0 notes
cvereport · 4 years ago
Text
CVE-2021-32675
Redis is an open source, in-memory database that persists on disk. When parsing an incoming Redis Standard Protocol (RESP) request, Redis allocates memory according to user-specified values which determine the number of elements (in the multi-bulk header) and size of each element (in the bulk header). An attacker delivering specially crafted requests over multiple connections can cause the server to allocate significant amount of memory. Because the same parsing mechanism is used to handle authentication requests, this vulnerability can also be exploited by unauthenticated users. The problem is fixed in Redis versions 6.2.6, 6.0.16 and 5.0.14. An additional workaround to mitigate this problem without patching the redis-server executable is to block access to prevent unauthenticated users from connecting to Redis. This can be done in different ways: Using network access control tools like firewalls, iptables, security groups, etc. or Enabling TLS and requiring users to authenticate using client side certificates. source https://cve.report/CVE-2021-32675
0 notes
rrloading184 · 4 years ago
Text
Docker Machine Xhyve
Tumblr media
Elasticsearch will then only be accessible from the host machine itself. The Docker named volumes data01, data02, and data03 store the node data directories so the data persists across restarts. If they don’t already exist, docker-compose creates them when you bring up the cluster. Make sure Docker Engine is allotted at least 4GiB of memory. Docker Engine 1.12 introduced a new swarm mode for natively managing a cluster of Docker Engines called a swarm. Docker swarm mode implements Raft Consensus Algorithm and does not require using external key value store anymore, such as Consul or etcd. If you want to run a swarm cluster on a developer’s machine, there are several options.
« Install Elasticsearch with Windows MSI InstallerInstall Elasticsearch on macOS with Homebrew »
Elasticsearch is also available as Docker images.The images use centos:8 as the base image.
A list of all published Docker images and tags is available atwww.docker.elastic.co. The source filesare inGithub.
This package contains both free and subscription features.Start a 30-day trial to try out all of the features.
Obtaining Elasticsearch for Docker is as simple as issuing a docker pull commandagainst the Elastic Docker registry.
To start a single-node Elasticsearch cluster for development or testing, specifysingle-node discovery to bypass the bootstrap checks:
Starting a multi-node cluster with Docker Composeedit
To get a three-node Elasticsearch cluster up and running in Docker,you can use Docker Compose:
This sample docker-compose.yml file uses the ES_JAVA_OPTSenvironment variable to manually set the heap size to 512MB. We do not recommendusing ES_JAVA_OPTS in production. See Manually set the heap size.
This sample Docker Compose file brings up a three-node Elasticsearch cluster.Node es01 listens on localhost:9200 and es02 and es03 talk to es01 over a Docker network.
Please note that this configuration exposes port 9200 on all network interfaces, and given howDocker manipulates iptables on Linux, this means that your Elasticsearch cluster is publically accessible,potentially ignoring any firewall settings. If you don’t want to expose port 9200 and instead usea reverse proxy, replace 9200:9200 with 127.0.0.1:9200:9200 in the docker-compose.yml file.Elasticsearch will then only be accessible from the host machine itself.
The Docker named volumesdata01, data02, and data03 store the node data directories so the data persists across restarts.If they don’t already exist, docker-compose creates them when you bring up the cluster.
Make sure Docker Engine is allotted at least 4GiB of memory.In Docker Desktop, you configure resource usage on the Advanced tab in Preference (macOS)or Settings (Windows).
Docker Compose is not pre-installed with Docker on Linux.See docs.docker.com for installation instructions:Install Compose on Linux
Run docker-compose to bring up the cluster:
Submit a _cat/nodes request to see that the nodes are up and running:
Log messages go to the console and are handled by the configured Docker logging driver.By default you can access logs with docker logs. If you would prefer the Elasticsearchcontainer to write logs to disk, set the ES_LOG_STYLE environment variable to file.This causes Elasticsearch to use the same logging configuration as other Elasticsearch distribution formats.
Tumblr media
To stop the cluster, run docker-compose down.The data in the Docker volumes is preserved and loadedwhen you restart the cluster with docker-compose up.To delete the data volumes when you bring down the cluster,specify the -v option: docker-compose down -v.
See Encrypting communications in an Elasticsearch Docker Container andRun the Elastic Stack in Docker with TLS enabled.
The following requirements and recommendations apply when running Elasticsearch in Docker in production.
The vm.max_map_count kernel setting must be set to at least 262144 for production use.
How you set vm.max_map_count depends on your platform:
Linux
The vm.max_map_count setting should be set permanently in /etc/sysctl.conf:
To apply the setting on a live system, run:
macOS with Docker for Mac
The vm.max_map_count setting must be set within the xhyve virtual machine:
From the command line, run:
Press enter and use`sysctl` to configure vm.max_map_count:
To exit the screen session, type Ctrl a d.
Windows and macOS with Docker Desktop
The vm.max_map_count setting must be set via docker-machine:
Windows with Docker Desktop WSL 2 backend
The vm.max_map_count setting must be set in the docker-desktop container:
Configuration files must be readable by the elasticsearch useredit
By default, Elasticsearch runs inside the container as user elasticsearch usinguid:gid 1000:0.
One exception is Openshift,which runs containers using an arbitrarily assigned user ID.Openshift presents persistent volumes with the gid set to 0, which works without any adjustments.
If you are bind-mounting a local directory or file, it must be readable by the elasticsearch user.In addition, this user must have write access to the config, data and log dirs(Elasticsearch needs write access to the config directory so that it can generate a keystore).A good strategy is to grant group access to gid 0 for the local directory.
For example, to prepare a local directory for storing data through a bind-mount:
Tumblr media
You can also run an Elasticsearch container using both a custom UID and GID. Unless youbind-mount each of the config, data` and logs directories, you must passthe command line option --group-add 0 to docker run. This ensures that the userunder which Elasticsearch is running is also a member of the root (GID 0) group inside thecontainer.
As a last resort, you can force the container to mutate the ownership ofany bind-mounts used for the data and log dirs through theenvironment variable TAKE_FILE_OWNERSHIP. When you do this, they will be owned byuid:gid 1000:0, which provides the required read/write access to the Elasticsearch process.
Increased ulimits for nofile and nprocmust be available for the Elasticsearch containers.Verify the init systemfor the Docker daemon sets them to acceptable values.
To check the Docker daemon defaults for ulimits, run:
If needed, adjust them in the Daemon or override them per container.For example, when using docker run, set:
Swapping needs to be disabled for performance and node stability.For information about ways to do this, see Disable swapping.
If you opt for the bootstrap.memory_lock: true approach,you also need to define the memlock: true ulimit in theDocker Daemon,or explicitly set for the container as shown in the sample compose file.When using docker run, you can specify:
The image exposesTCP ports 9200 and 9300. For production clusters, randomizing thepublished ports with --publish-all is recommended,unless you are pinning one container per host.
By default, Elasticsearch automatically sizes JVM heap based on a nodes’sroles and the total memory available to the node’s container. Werecommend this default sizing for most production environments. If needed, youcan override default sizing by manually setting JVM heap size.
To manually set the heap size in production, bind mount a JVMoptions file under /usr/share/elasticsearch/config/jvm.options.d thatincludes your desired heap size settings.
Tumblr media
For testing, you can also manually set the heap size using the ES_JAVA_OPTSenvironment variable. For example, to use 16GB, specify -eES_JAVA_OPTS='-Xms16g -Xmx16g' with docker run. The ES_JAVA_OPTS variableoverrides all other JVM options. The ES_JAVA_OPTS variable overrides all otherJVM options. We do not recommend using ES_JAVA_OPTS in production. Thedocker-compose.yml file above sets the heap size to 512MB.
Pin your deployments to a specific version of the Elasticsearch Docker image. Forexample docker.elastic.co/elasticsearch/elasticsearch:7.12.0.
You should use a volume bound on /usr/share/elasticsearch/data for the following reasons:
The data of your Elasticsearch node won’t be lost if the container is killed
Elasticsearch is I/O sensitive and the Docker storage driver is not ideal for fast I/O
It allows the use of advancedDocker volume plugins
If you are using the devicemapper storage driver, do not use the default loop-lvm mode.Configure docker-engine to usedirect-lvm.
Consider centralizing your logs by using a differentlogging driver. Alsonote that the default json-file logging driver is not ideally suited forproduction use.
When you run in Docker, the Elasticsearch configuration files are loaded from/usr/share/elasticsearch/config/.
To use custom configuration files, you bind-mount the filesover the configuration files in the image.
You can set individual Elasticsearch configuration parameters using Docker environment variables.The sample compose file and thesingle-node example use this method.
To use the contents of a file to set an environment variable, suffix the environmentvariable name with _FILE. This is useful for passing secrets such as passwords to Elasticsearchwithout specifying them directly.
For example, to set the Elasticsearch bootstrap password from a file, you can bind mount thefile and set the ELASTIC_PASSWORD_FILE environment variable to the mount location.If you mount the password file to /run/secrets/bootstrapPassword.txt, specify:
You can also override the default command for the image to pass Elasticsearch configurationparameters as command line options. For example:
While bind-mounting your configuration files is usually the preferred method in production,you can also create a custom Docker imagethat contains your configuration.
Create custom config files and bind-mount them over the corresponding files in the Docker image.For example, to bind-mount custom_elasticsearch.yml with docker run, specify:
The container runs Elasticsearch as user elasticsearch usinguid:gid 1000:0. Bind mounted host directories and files must be accessible by this user,and the data and log directories must be writable by this user.
By default, Elasticsearch will auto-generate a keystore file for secure settings. Thisfile is obfuscated but not encrypted. If you want to encrypt yoursecure settings with a password, you must use theelasticsearch-keystore utility to create a password-protected keystore andbind-mount it to the container as/usr/share/elasticsearch/config/elasticsearch.keystore. In order to providethe Docker container with the password at startup, set the Docker environmentvalue KEYSTORE_PASSWORD to the value of your password. For example, a dockerrun command might have the following options:
In some environments, it might make more sense to prepare a custom image that containsyour configuration. A Dockerfile to achieve this might be as simple as:
You could then build and run the image with:
Some plugins require additional security permissions.You must explicitly accept them either by:
Attaching a tty when you run the Docker image and allowing the permissions when prompted.
Inspecting the security permissions and accepting them (if appropriate) by adding the --batch flag to the plugin install command.
See Plugin managementfor more information.
You now have a test Elasticsearch environment set up. Before you startserious development or go into production with Elasticsearch, you must do some additionalsetup:
Learn how to configure Elasticsearch.
Configure important Elasticsearch settings.
Configure important system settings.
« Install Elasticsearch with Windows MSI InstallerInstall Elasticsearch on macOS with Homebrew »
Most Popular
-->
This section lists terms and definitions you should be familiar with before getting deeper into Docker. For further definitions, see the extensive glossary provided by Docker.
Container image: A package with all the dependencies and information needed to create a container. An image includes all the dependencies (such as frameworks) plus deployment and execution configuration to be used by a container runtime. Usually, an image derives from multiple base images that are layers stacked on top of each other to form the container's filesystem. An image is immutable once it has been created.
Dockerfile: A text file that contains instructions for building a Docker image. It's like a batch script, the first line states the base image to begin with and then follow the instructions to install required programs, copy files, and so on, until you get the working environment you need.
Brew Docker-machine-driver-xhyve
Build: The action of building a container image based on the information and context provided by its Dockerfile, plus additional files in the folder where the image is built. You can build images with the following Docker command:
Container: An instance of a Docker image. A container represents the execution of a single application, process, or service. It consists of the contents of a Docker image, an execution environment, and a standard set of instructions. When scaling a service, you create multiple instances of a container from the same image. Or a batch job can create multiple containers from the same image, passing different parameters to each instance.
Volumes: Offer a writable filesystem that the container can use. Since images are read-only but most programs need to write to the filesystem, volumes add a writable layer, on top of the container image, so the programs have access to a writable filesystem. The program doesn't know it's accessing a layered filesystem, it's just the filesystem as usual. Volumes live in the host system and are managed by Docker.
Tag: A mark or label you can apply to images so that different images or versions of the same image (depending on the version number or the target environment) can be identified.
Multi-stage Build: Is a feature, since Docker 17.05 or higher, that helps to reduce the size of the final images. In a few sentences, with multi-stage build you can use, for example, a large base image, containing the SDK, for compiling and publishing the application and then using the publishing folder with a small runtime-only base image, to produce a much smaller final image.
Docker Machine Xhyve Game
Repository (repo): A collection of related Docker images, labeled with a tag that indicates the image version. Some repos contain multiple variants of a specific image, such as an image containing SDKs (heavier), an image containing only runtimes (lighter), etc. Those variants can be marked with tags. A single repo can contain platform variants, such as a Linux image and a Windows image.
Registry: A service that provides access to repositories. The default registry for most public images is Docker Hub (owned by Docker as an organization). A registry usually contains repositories from multiple teams. Companies often have private registries to store and manage images they've created. Azure Container Registry is another example.
Multi-arch image: For multi-architecture, it's a feature that simplifies the selection of the appropriate image, according to the platform where Docker is running. For example, when a Dockerfile requests a base image mcr.microsoft.com/dotnet/sdk:5.0 from the registry, it actually gets 5.0-nanoserver-1909, 5.0-nanoserver-1809 or 5.0-buster-slim, depending on the operating system and version where Docker is running.
Docker Hub: A public registry to upload images and work with them. Docker Hub provides Docker image hosting, public or private registries, build triggers and web hooks, and integration with GitHub and Bitbucket.
Azure Container Registry: A public resource for working with Docker images and its components in Azure. This provides a registry that's close to your deployments in Azure and that gives you control over access, making it possible to use your Azure Active Directory groups and permissions.
Docker Trusted Registry (DTR): A Docker registry service (from Docker) that can be installed on-premises so it lives within the organization's datacenter and network. It's convenient for private images that should be managed within the enterprise. Docker Trusted Registry is included as part of the Docker Datacenter product. For more information, see Docker Trusted Registry (DTR).
Docker Community Edition (CE): Development tools for Windows and macOS for building, running, and testing containers locally. Docker CE for Windows provides development environments for both Linux and Windows Containers. The Linux Docker host on Windows is based on a Hyper-V virtual machine. The host for Windows Containers is directly based on Windows. Docker CE for Mac is based on the Apple Hypervisor framework and the xhyve hypervisor, which provides a Linux Docker host virtual machine on macOS X. Docker CE for Windows and for Mac replaces Docker Toolbox, which was based on Oracle VirtualBox.
Docker Enterprise Edition (EE): An enterprise-scale version of Docker tools for Linux and Windows development.
Compose: A command-line tool and YAML file format with metadata for defining and running multi-container applications. You define a single application based on multiple images with one or more .yml files that can override values depending on the environment. After you've created the definitions, you can deploy the whole multi-container application with a single command (docker-compose up) that creates a container per image on the Docker host.
Cluster: A collection of Docker hosts exposed as if it were a single virtual Docker host, so that the application can scale to multiple instances of the services spread across multiple hosts within the cluster. Docker clusters can be created with Kubernetes, Azure Service Fabric, Docker Swarm and Mesosphere DC/OS.
Docker Machine Xhyve Tool
Orchestrator: A tool that simplifies management of clusters and Docker hosts. Orchestrators enable you to manage their images, containers, and hosts through a command-line interface (CLI) or a graphical UI. You can manage container networking, configurations, load balancing, service discovery, high availability, Docker host configuration, and more. An orchestrator is responsible for running, distributing, scaling, and healing workloads across a collection of nodes. Typically, orchestrator products are the same products that provide cluster infrastructure, like Kubernetes and Azure Service Fabric, among other offerings in the market.
Tumblr media
0 notes
sololinuxes · 5 years ago
Text
Script to block countries in iptables - Bloquear países
Tumblr media
Script to block countries in Iptables - Bloquear países. Todos los propietarios de Servidores o VPS, padecemos de la gran lacra  de los sitios web... evidentemente hablamos de los intentos de intrusión, dDOS, ataques constantes, rastreo de puertos, spammers, etc... etc... La gran mayoría de este tipo de situaciones que nos pueden generar auténticos dolores de cabeza, provienen de los mismos países, China, Rusia, India, etc... Entonces yo me pregunto... realmente es necesario admitir a un país como China?, la respuesta es no, no es necesario, pues no te reportara ningún beneficio (salvo casos muy puntuales), solo problemas. Soy consciente que mi afirmación puede ser discutida, incluso criticada, pero vamos a ver... seamos sinceros, acaso piensas que un chino está interesado en tu tienda de zapatos, tu periódico en castellano, tus servicios en la red, etc..., pues no, no les interesas para nada, su único interés es hacerse con tu servicio, por ejemplo tu SMTP para enviar su mier** de spam que lo único que hará sera perjudicar la reputación de tu IP o dominio. No te lo pienses más y no dudes, si tienes este problema bloquea el país al completo.
Tumblr media
Script to block countries - Bloquear países   Hace ya un tiempo publicamos un script "bash", que descargaba el listado de IP's de un país y las aplicaba en Iptables. Lamentablemente aquel script ya está obsoleto... y por ello te presento la nueva versión del script bash "block-countries.sh", que viene con muchas mejoras. Principales novedades: Programación mejorada Definir puertos permitidos (por defecto 80 y 443) Reducción del proceso de las reglas Solo busca la coincidencia en el primer octeto del rango IP Se permite al acceso desde un puerto a definir del país bloqueado Carga el listado de país con iptables-restore etc... En la antigua versión cargar y aplicar el listado de IP's, de un país como China, podía tomar más de una hora. En esta nueva versión, menos de 30 segundos y todo gracias a el uso de "iptables-restore", para que me entiendas mejor... restaura tablas IP a partir de datos especificados en STDIN. AVISO: Este script es para Centos, si utilizas Debian o Ubuntu debes realizar unas modificaciones. Instrucciones al final del artículo. Sin más preámbulos vemos el script.  
Script block countries en Iptables
Desde consola / terminal y como root creamos el archivo "block-countries.sh" (países predeterminados, Rusia y China). nano block-countries.sh Copia y pega el script. #!/bin/bash #Use ISO code countries ### ### Block all traffic from RUSIA (ru) and CHINA (cn) ISO="ru cn" ### codigo de país a bloquear ### Set PATH ### IPT=/sbin/iptables WGET=/usr/bin/wget EGREP=/bin/egrep ### No editing below ### CBLIST="countrydrop" ZONEROOT="/var/iptables" IPTCBRESTORE="/etc/sysconfig/iptables.cb" IPTCBDEVICE=eth0 ALLOWPORTS=80,443 ALLOWSUBNET=192.168.0.0/255.255.0.0 MAXZONEAGE=7 DLROOT="http://www.ipdeny.com/ipblocks/data/countries" cleanOldRules(){ $IPT -L $CBLIST > /dev/null 2>&1 if ; then $IPT -D INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST $IPT -D OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST $IPT -D FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST fi $IPT -F $CBLIST $IPT -X $CBLIST for i in `$IPT -L -n | grep Chain | cut -f 2 -d ' ' | grep '\-$CBLIST'` do $IPT -F ${i} $IPT -X ${i} done } updateZoneFiles() { ZONEARCH=${ZONEROOT}/arch mkdir -p ${ZONEARCH} find ${ZONEROOT} -maxdepth 1 -mindepth 1 -ctime +${MAXZONEAGE} -exec mv {} ${ZONEARCH} \; for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone if ; then printf "Zone file %s is new enough - no update required.\n" $tDB else # get fresh zone file if it is newer than MAXZONEAGE days $WGET -O $tDB $DLROOT/$c.zone fi done oldzones=`find ${ZONEROOT} -mindepth 1 -maxdepth 1 -type f -exec basename {} \; | cut -f 1 -d '.'` # Archive old zones no longer blocked for z in $oldzones ; do archme=${c} for c in $ISO ; do if ; then archme="X"; fi done if ; then mv ${archme} ${ZONEARCH} else printf "Working from previous zone file for %s\n" ${z} fi done } createIPTLoadFile() { printf "# Generated by %s on" $0 > ${IPTCBRESTORE} printf "%s " `date` >> ${IPTCBRESTORE} printf "\n*filter\n" >> ${IPTCBRESTORE} # Create CBLIST chain printf ":$CBLIST - \n" >> ${IPTCBRESTORE} printf "%s INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" > ${IPTCBRESTORE}.tmp printf "%s OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST\n" "-I" >> ${IPTCBRESTORE}.tmp printf "%s FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST\n" "-I" >> ${IPTCBRESTORE}.tmp if ; then printf "Blocking all traffic from country - no ports allowed\n" else printf "%s $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j RETURN\n" "-I">> ${IPTCBRESTORE}.tmp fi if ; then printf "Blocking all traffic from country - no subnets excluded\n" else printf "%s $CBLIST -s ${ALLOWSUBNET} -j RETURN\n" "-I">> ${IPTCBRESTORE}.tmp fi for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone # country specific log message SPAMDROPMSG="iptables: ${c}-Country-Drop: " # Create drop chain for identified packets CBLISTDROP=${c}-${CBLIST}-DROP printf ":${CBLISTDROP} - \n" >> ${IPTCBRESTORE} printf "%s ${CBLISTDROP} -j LOG --log-prefix \"$SPAMDROPMSG\"\n" "-A" >> ${IPTCBRESTORE}.tmp printf "%s ${CBLISTDROP} -j DROP\n" "-A" >> ${IPTCBRESTORE}.tmp # Load IP ranges into chains correlating to first octet BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do topip=`echo $ipblock | cut -f 1 -d '.'` chainExists=`grep -c :${topip}-${CBLIST} ${IPTCBRESTORE}` if ; then printf "Creating chain for octet %s\n" ${topip} printf ":$topip-$CBLIST - \n" >> ${IPTCBRESTORE} sip=${topip}.0.0.0/8 printf "%s $CBLIST -s ${sip} -j $topip-$CBLIST\n" "-A" >> ${IPTCBRESTORE}.tmp fi printf " Adding rule for %s to chain for octet %s\n" ${ipblock} ${topip} printf "%s $topip-$CBLIST -s $ipblock -j ${CBLISTDROP}\n" "-A" >> ${IPTCBRESTORE}.tmp done done cat ${IPTCBRESTORE}.tmp >> ${IPTCBRESTORE} && rm -f ${IPTCBRESTORE}.tmp printf "COMMIT\n# Completed on " >> ${IPTCBRESTORE} printf "%s " `date` >> ${IPTCBRESTORE} printf "\n" >> ${IPTCBRESTORE} } directLoadTables() { # Create CBLIST chain $IPT -N $CBLIST $IPT -I INPUT ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST $IPT -I OUTPUT ${IPTCBDEVICE:+-o }${IPTCBDEVICE} -j $CBLIST $IPT -I FORWARD ${IPTCBDEVICE:+-i }${IPTCBDEVICE} -j $CBLIST if ; then printf "Blocking all traffic from country - no ports allowed\n" else $IPT -I $CBLIST -p tcp -m multiport --dports ${ALLOWPORTS} -j RETURN fi if ; then printf "Blocking all traffic from country - no subnets allowed\n" else $IPT -I $CBLIST -s ${ALLOWSUBNET} -j RETURN fi for c in $ISO do # local zone file tDB=$ZONEROOT/$c.zone # country specific log message SPAMDROPMSG="$c Country Drop" # Create drop chain for identified packets CBLISTDROP=${c}-${CBLIST}-DROP $IPT -N ${CBLISTDROP} $IPT -A ${CBLISTDROP} -j LOG --log-prefix "$SPAMDROPMSG" $IPT -A ${CBLISTDROP} -j DROP # Load IP ranges into chains correlating to first octet BADIPS=$(egrep -v "^#|^$" $tDB) for ipblock in $BADIPS do topip=`echo $ipblock | cut -f 1 -d '.'` $IPT -L $topip-$CBLIST > /dev/null 2>&1 if ; then printf "Creating chain for octet %s\n" ${topip} $IPT -N $topip-$CBLIST sip=${topip}.0.0.0/8 $IPT -A $CBLIST -s ${sip} -j $topip-$CBLIST fi printf " Adding rule for %s to chain for octet %s\n" ${ipblock} ${topip} $IPT -A $topip-$CBLIST -s $ipblock -j ${CBLISTDROP} done done } loadTables() { createIPTLoadFile ${IPT}-restore -n ${IPTCBRESTORE} #directLoadTables printf "Country block instituted for: %s\n" "$ISO" } # create a dir && /bin/mkdir -p $ZONEROOT # clean old rules cleanOldRules # update zone files as needed updateZoneFiles # create a new iptables list loadTables exit 0 Guarda y cierra el editor.
Tumblr media
  Ejecuta el script: bash block-countries.sh Como te comente anteriormente, este script es muy rápido. Ejemplo de salida: --2018-02-07 06:37:55-- http://www.ipdeny.com/ipblocks/data/countries/cn.zone Resolviendo www.ipdeny.com (www.ipdeny.com)... 192.241.240.22 Conectando con www.ipdeny.com (www.ipdeny.com):80... conectado. Petición HTTP enviada, esperando respuesta... 200 OK Longitud: 125774 (123K) Grabando a: “/var/iptables/cn.zone” 100% 125.774 324KB/s en 0,4s 2018-02-07 06:37:56 (324 KB/s) - “/var/iptables/cn.zone” guardado Working from previous zone file for cn Creating chain for octet 1 Adding rule for 1.0.1.0/24 to chain for octet 1 Adding rule for 1.0.2.0/23 to chain for octet 1 Adding rule for 1.0.8.0/21 to chain for octet 1 Adding rule for 1.0.32.0/19 to chain for octet 1 Adding rule for 1.1.0.0/24 to chain for octet 1 Adding rule for 1.1.2.0/23 to chain for octet 1 Adding rule for 1.1.4.0/22 to chain for octet 1 ............................................. .............................................. Ya lo tenemos instalado y ejecutándose Script to block countries, te recomiendo que crees una tarea cron para que se actualice el listado de ip's. Por ejemplo: @weekly /path/to/block-countries.sh y lo ejecutamos. /path/to/block-countries.sh Si prefieres descargar el script "block countries"directamente, lo encontraras a continuación.
Tumblr media
  Uso del Script to block countries en Debian, Ubuntu y derivados Este Script to block countries fue creado para CentOS. En Ubuntu o Debian se deben utilizar otras rutas que pasamos a detallar. Primero ejecuta el siguiente comando, para realizar una instalacion completa. sudo apt install iptables-persistent netfilter-persistent Te solicitara que aceptes la persistencia en V4 y V6. Responde YES.
Tumblr media
Script to block countries Al terminar reiniciamos iptables. sudo service iptables restart En el script to block countries buscas la siguiente sección. ### No editing below ### CBLIST="countrydrop" ZONEROOT="/var/iptables" IPTCBRESTORE="/etc/sysconfig/iptables.cb" IPTCBDEVICE=eth0 ALLOWPORTS=80,443 ALLOWSUBNET=192.168.0.0/255.255.0.0 MAXZONEAGE=7 DLROOT="http://www.ipdeny.com/ipblocks/data/countries" y la cambias por... ### No editing below ### CBLIST="countrydrop" ZONEROOT="/var/iptables" IPTCBRESTORE="/etc/iptables/rules.v4" IPTCBDEVICE=eth0 ALLOWPORTS=80,443 ALLOWSUBNET=192.168.0.0/255.255.0.0 MAXZONEAGE=7 DLROOT="http://www.ipdeny.com/ipblocks/data/countries" Ahora, ya puedes ejecutar el script anterior con las modificaciones para Debian o Ubuntu. El resto de pasos son los mismos. Que disfrutes el script.   Recursos Listas de países y sus ip. Nota Final Asegurate que estas utilizando la interfaz... IPTCBDEVICE=eth0 Si no es así, modificas el nombre.   Canales de Telegram: Canal SoloLinux – Canal SoloWordpress Espero que este articulo te sea de utilidad, puedes ayudarnos a mantener el servidor con una donación (paypal), o también colaborar con el simple gesto de compartir nuestros artículos en tu sitio web, blog, foro o redes sociales. Script to block countries in iptables - Bloquear países.   Read the full article
0 notes
suzukiapple · 6 years ago
Text
Ubuntuでv6プラス環境下にVPNサーバを構築する
自宅のUbuntuサーバへ外出先からアクセスしたい場面が何度かあった。 アクセスしうるポートを全て外部へ解放しておくのはセキュリティ上の問題があるため、VPNで自宅LANへ接続することを考えた。
自宅はv6プラスでインターネットへ繋がっている。 v6プラス環境下の場合、自由に使うことのできるポートが限られているため、L2TP/IPsecなど使用するポートが決まっているものは構築できない。 そこでOpenVPNを使用してv6プラス環境下にVPNサーバを構築する。
使用可能なポート番号を調べる
http://ipv4.web.fc2.com/map-e.html にアクセスする。 Ubuntuサーバに割り当てられているIPv6アドレスのプレフィックスを入力し、「計算」ボタンを押す。 ポート番号フィールドに使用可能なポートの一覧が表示される。 この240個の中であれば自由に使うことできるので適当に1つ選ぶ。 今回は例として5000番ポートを選んだとする。
v6プラス環境下でVPNの通信にUDPを使った場合、VPNサーバへ接続はできるがDNSの名前解決ができなくなる現象が発生する。 そのためTCPを使うようにする。 外部から来るTCP5000番ポートの通信がUbuntuサーバへ向くようにルータのポート変換設定を行う。 ルータの設定方法はメーカー提供の説明書等をご参照ください。
OpenVPNの設定
UbuntuサーバへOpenVPNをインストール。
$ sudo apt install openvpn
Easy RSAをダウンロード。 作業場所は特にどこでも問題ないです。
$ git clone https://github.com/OpenVPN/easy-rsa.git $ cd easy-rsa/easyrsa3
初期設定を行う。
$ ./easyrsa init-pki init-pki complete; you may now create a CA or requests. Your newly created PKI dir is: /tmp/easy-rsa/easyrsa3/pki
CA証明書を作成する。 CA Key Passphraseを聞かれるので、4〜1023文字の範囲で何かしら入力する。 Common Nameはユーザ名、ホスト名、サーバ名などご自由にどうぞ。
$ ./easyrsa build-ca Enter New CA Key Passphrase:(パスフレーズを入力) Re-Enter New CA Key Passphrase:(パスフレーズを再度入力) Generating RSA private key, 2048 bit long modulus .................+++ .......+++ e is 65537 (0x10001) You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Common Name (eg: your user, host, or server name) [Easy-RSA CA]:(ユーザ名などを入力) CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: /tmp/easy-rsa/easyrsa3/pki/ca.crt
生成された鍵を/etc/openvpnへコピーする。
$ sudo cp pki/ca.crt /etc/openvpn
サーバ証明書を作成する。 パスフレーズを聞かれるので、CA証明書を作成したときのものを入力する。
$ ./easyrsa build-server-full server nopass Using SSL: openssl OpenSSL 1.0.2g 1 Mar 2016 Generating a 2048 bit RSA private key .................+++ .......+++ writing new private key to '/tmp/easy-rsa/easyrsa3/pki/easy-rsa-XXX/tmp.XXX' ----- Using configuration from /tmp/easy-rsa/easyrsa3/pki/easy-rsa-XXX/tmp.XXX Enter pass phrase for /tmp/easy-rsa/easyrsa3/pki/private/ca.key:(パスフレーズを入力) Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :ASN.1 12:'server' Certificate is to be certified until Oct 16 11:08:07 2022 GMT (1080 days) Write out database with 1 new entries Data Base Updated
生成された鍵を/etc/openvpnへコピーする。
$ sudo cp pki/issued/server.crt /etc/openvpn $ sudo cp pki/private/server.key /etc/openvpn
DH鍵を作成する。 鍵の生成には時間がかかるのでしばらく待つ。
$ ./easyrsa gen-dh Using SSL: openssl OpenSSL 1.0.2g 1 Mar 2016 Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time ..........+........................+.........+.......... ..................................................++*++* DH parameters of size 2048 created at /tmp/easy-rsa/easyrsa3/pki/dh.pem
生成された鍵をコピーする。
$ sudo cp pki/dh.pem /etc/openvpn
クライアント証明書を作成する。 パスフレーズを聞かれるので、CA証明書を作成したときのものを入力する。
$ ./easyrsa gen-crl Using SSL: openssl OpenSSL 1.0.2g 1 Mar 2016 Using configuration from /tmp/easy-rsa/easyrsa3/pki/easy-rsa-XXX/tmp.XXX Enter pass phrase for /tmp/easy-rsa/easyrsa3/pki/private/ca.key:(パスフレーズを入力) An updated CRL has been created. CRL file: /tmp/easy-rsa/easyrsa3/pki/crl.pem
生成された鍵をコピーする。
$ sudo cp pki/crl.pem /etc/openvpn $ sudo chmod o+r /etc/openvpn/crl.pem
OpenVPNの設定ファイルを作成する。 /etc/openvpn/server.conf
port 5000 proto tcp6 dev tun ca ca.crt cert server.crt key server.key dh dh.pem crl-verify crl.pem ifconfig-pool-persist ipp.txt server 10.8.0.0 255.255.255.0 push "redirect-gateway def1 bypass-dhcp" push "route 10.8.0.0 255.255.255.0" push "dhcp-option DNS 8.8.8.8" push "dhcp-option DNS 8.8.4.4" client-to-client keepalive 10 120 comp-lzo yes push "comp-lzo yes" user nobody group nogroup persist-key persist-tun status /var/log/openvpn-status.log log /var/log/openvpn.log log-append /var/log/openvpn.log verb 3
port(ポート番号)の値は、前章「使用可能なポート番号を調べる」で決めたポート番号を指定する。 proto(通信プロトコル)は、v6プラスの制約によりtcpを用いる。 UbuntuサーバへIPv6で接続する場合は「proto tcp6」, IPv4で接続する場合は「proto tcp」とする。 DNSは、Google Public DNS(8.8.8.8, 8.8.4.4)を使うことにした。
IPフォワーディングの設定
/etc/sysctl.conf
net.ipv4.ip_forward=1
を追記。
設定の反映。
sudo sysctl -p
IPマスカレードの設定
/etc/rc.local
sudo iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
を追記。 書いたコマンドをそのまま打つか、サーバ再起動させて反映。
OpenVPNの起動
$ sudo systemctl start [email protected]
プロセスが起動されているか確認。
$ ps aux | grep openvpn | grep -v grep
サーバ再起動時にOpenVPNが自動起動されるよう設定。 [email protected]がenabled, openvpn.serviceがdisabledになっていることを確認。
$ sudo systemctl enable [email protected] $ sudo systemctl disable openvpn.service $ systemctl is-enabled [email protected] openvpn.service enabled disabled
クライアント用秘密鍵の作成
引数のusernameのところはご自由に決め���れます。 PEM pass phraseを聞かれるので、4〜1024文字の範囲で何かしら入力する。 続けてパスフレーズを聞かれるので、CA証明書を作成したときのものを入力する。
$ cd easy-rsa/easyrsa3 $ ./easyrsa build-client-full username Using SSL: openssl OpenSSL 1.0.2g 1 Mar 2016 Generating a 2048 bit RSA private key .................+++ .......+++ writing new private key to '/tmp/easy-rsa/easyrsa3/pki/easy-rsa-XXX/tmp.XXX' Enter PEM pass phrase:(クライアント用秘密鍵のパスフレーズを入力) Verifying - Enter PEM pass phrase:(クライアント用秘密鍵のパスフレーズを再度入力) ----- Using configuration from /tmp/easy-rsa/easyrsa3/pki/easy-rsa-XXX/tmp.XXX Enter pass phrase for /tmp/easy-rsa/easyrsa3/pki/private/ca.key:(CA証明書のパスフレーズを入力) Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows commonName :ASN.1 12:'username' Certificate is to be certified until Oct 16 11:52:30 2022 GMT (1080 days) Write out database with 1 new entries Data Base Updated
下記3ファイルをVPNサーバへ接続するクライアントPCへコピーする。 FTPクライアントやSCPなどお好きな方法でどうぞ。
/etc/openvpn/ca.crt
easy-rsa/easyrsa3/pki/issued/username.crt
easy-rsa/easyrsa3/pki/private/username.key
接続端末1つにつきクライアント用秘密鍵を1つ用意する必要があるため、 必要な分だけクライアント用秘密鍵作成作業を繰り返す。
Ubuntuサーバでの作業は以上。
クライアントPCの設定
次はクライアントPCへVPNサーバへ接続するための設定を行う。 自分の場合、クライアントPCはMacのため、Tunnelblickを使う。 https://tunnelblick.net/downloads.html からStable版をダウンロード。
接続用の設定ファイルを作成する。 保存先のディレクトリ・設定ファイルの名前は自由だが、設定ファイルの拡張子は「.ovpn」にすること。
xxxxx.com.ovpn
client dev tun proto tcp6 remote xxxxx.com 5000 resolv-retry infinite nobind persist-key persist-tun ca ca.crt cert username.crt key username.key verb 3
remoteの値は、VPNサーバのFQDNもしくはIPアドレスと、ポート番号を指定する。 protoの値は、server.confへ書いたものに合わせる。 作成した設定ファイルと同じディレクトリに鍵ファイル3つ(ca.crt, username.crt, username.key)を格納する。
作成した設定ファイルをメニューバーに表示されているトンネルアイコンにドラッグ&ドロップ。 トンネルアイコン→Connect xxxxx.comをクリック。 接続状況を表すウィンドウに緑文字で「Connected xx:xx(接続時間)」と表示されればOK。
自宅LAN内にあるサーバにアクセスできるか、およびブラウザなどで外部のwebページが見られるかを確認。 クライアントPCが自宅LAN内に繋がっていてもVPN接続自体は可能だが動作確認にならないため、 テザリングなどを用いて外部から自宅LAN内への接続確認を行う。
参考: https://qiita.com/noraworld/items/2fe6be489e1d93c748b8 https://www.akakagemaru.info/port/v6-portfw.html http://akakabu.way-nifty.com/blog/2018/02/ipv6vpnvpn-ov-1.html https://blog.n-z.jp/blog/2018-03-08-openvpn-deprecated-comp-lzo.html
0 notes
wolfliving · 8 years ago
Text
How to (attempt to) secure your Raspberry Pi against IoT hacker attacks
*Gee, that doesn’t look difficult, painful, or time-consuming.
https://makezine.com/2017/09/07/secure-your-raspberry-pi-against-attackers/
Why would anyone hack a Raspberry Pi?
Its computing power can be abused for operations like mining cryptocurrency.
It can be used as a bounce point to attack other hosts, in order to cover the attacker’s tracks.
It’s an entry point to the rest of an internal network. An attacker can easily reach the file servers and try to install ransomware, obtain documents for blackmail, or manipulate the firewall and router settings to ensure persistent access in the future for later nefarious actions, either by attacking the web console of the router or performing uPNP manipulation to open up more ports to the Internet for attack.
Passwords
Change the default passwords — If you are installing a recent version of NOOBS or Raspbian, be sure to change the default password of the “pi” user to something that is long and hard to guess. A passphase like “iamasuckerfor5dollarmojitos” is much better than P@assword1! Even if you plan on disabling the account, this first step is basic protection in case you forget.
User Accounts
Your next step should be to disable the default Pi account in Raspbian. Before doing this, create a new account on the system. You can use the useradd command to do this, with some extra flags to specify that a new home directory be created for the user. Log in as the Pi user and issue the command:
$ sudo /usr/sbin/useradd --groups sudo -m makezine
Use your own username instead of “makezine.” This will create a new account, create a directory for the account (such as /home/makezine), and add the new account to the sudo group so the user can use the sudo command. Once the new user account is created we need to set a password for the account. You can do this using the command:
$ sudo passwd makezine
Next, reset the root password. Choose something long and hard to guess.
$ sudo passwd root
Finally, you’ll want to disable the Pi account:
$ sudo passwd --lock pi
Now you can log out of the Pi account and log in with your new account and password.
Securing SSH
By default, Raspbian installs a remote access shell (SSH) that can be accessed from anywhere. You can disable this by setting up SSH so that only machines with an authorized SSH key can log in. Back up your private keys in at least two locations you trust.
To set them up, edit the SSH configuration file using vi, or another text editor, with the command:
$ sudo vi /etc/ssh/sshd_config
Make sure the following lines are set and uncommented — meaning that the lines are in the file and they aren’t preceded with a hash tag symbol, which marks a line as a comment and ignores it for configuration purposes:
# Authentication: LoginGraceTime 120 PermitRootLogin no StrictModes yes RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys # To enable empty passwords, change to yes (NOT RECOMMENDED) PermitEmptyPasswords no # Change to yes to enable challenge-response passwords (beware issues with # some PAM modules and threads) ChallengeResponseAuthentication no # Change to no to disable tunnelled clear text passwords PasswordAuthentication no UsePAM no
The last line is very important since it will disable Pluggable Authentication Modules (PAM), or native Linux authentication, and only allow users to log in with a key. Next, generate an SSH key. You can do this with PuTTY on Windows or with the ssh-keygen command on Linux. Create a .ssh directory in your user’s home directory and an authorized_keys file with the following commands. Be sure to set the permissions properly (otherwise the key based authentication will fail):
$ mkdir ~/.ssh $ chmod 0700 ~/.ssh $ touch ~/.ssh/authorized_keys $ chmod 0600 ~/.ssh/authorized_keys
Next use your text editor to edit the authorized_keys file and paste in the public key you generated so you can log in. Be sure to restart SSH to ensure the changes take effect using the command:
$ sudo systemctl restart ssh
Firewall
Once you’ve locked down SSH, you’ll want to ensure that the iptables firewall is running on your Pi. For good measure, you can configure the firewall so that it logs a message whenever a firewall rule is activated and a connection is blocked. First make sure that iptables is installed using the command:
$ sudo apt-get install iptables iptables-persistent
Note that using the iptables firewall will require new kernel modules to be loaded. The easiest way to load them is to reboot your Pi. Once iptables is installed, go ahead and check the current iptables rules with the command:
$ sudo /sbin/iptables -L
This will list the rules, which are probably empty. You can save these rules off to a text file and edit it using the command:
$ sudo /sbin/iptables-save > /etc/iptables/rules.v4
This is the file that iptables-persistent uses when your system boots or reboots to make sure that the firewall is still running. Save, then edit the file so that it looks somewhat like the following (altering whatever rules you need):
$ sudo cat /etc/iptables/rules.v4 :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] # Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT # Accepts all established inbound connections -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allows all outbound traffic # You could modify this to only allow certain traffic -A OUTPUT -j ACCEPT # Allows SSH connections # The --dport number is the same as in /etc/ssh/sshd_config -A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT # log iptables denied calls (access via 'dmesg' command) -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7 # Reject all other inbound - default deny unless explicitly allowed policy: -A INPUT -j REJECT -A FORWARD -j REJECT COMMIT
Next, ensure your iptables are working properly. This can be tricky (((etc etc etc etc)))
3 notes · View notes
kureeeen · 6 years ago
Text
Kubernetes
Kubernetes 를 공부하면서 했던 메모.
Kubernetes
今こそ始めよう!Kubernetes 入門
History
Google 사내에서 이용하던 Container Cluster Manager “Borg” 에 착안하여 만들어진 Open Source Software (OSS)
2014년 6월 런칭
2015년 7월 version 1.0.
version 1.0 이후 Linux Foundation 의 Could Native Computing Foundation (CNCF) 로 이관되어 중립적 입장에서 개발
version 1.7 Production-Ready
De facto standard
2014년 11월 Google Cloud Platform (GCP) 가 Google Container Engine (GKE, 후에 Google Kuebernetes Engine) 제공 시작
2017년 2월 Microsoft Azure 가 Azure Container Service (AKS) 릴리즈
2017년 11월 Amazon Web Service (AWS) 가 Amazon Elastic Container Service for Kubernetese (Amazon EKS) 릴리즈
Kubernetes 로 가능한 일
Docker 를 Product 레벨에서 이용하기 위해서 고려해야 했던 점들
복수의 Docker Host 관리
Container 의 Scheduling
Rolling-Update
Scaling / Auto Scaling
Monitoring Container Live/Dead
Self Healing
Service Discovery
Load Balancing
Manage Data
Manage Workload
Manage Log
Infrastructure as Code
그 외 Ecosystem과의 연계와 확장
위 문제들을 해결하기 위해 Kubernetes 가 탄생
Kubernetes 에서는 YAML 형식 manifesto 사용
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: sample-deployment spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:latest ports: - containerPort: 80 ` **Kubernets 는,**
복수의 Docker Host 를 관리해서 container cluster 를 구축
같은 container 의 replica 로 실행하여 부하 분산과 장애에 대비 가능
부하에 따라 container 의 replica 수를 조절 (auto scaling) 가능
Disk I/O, Network 통신량 등의 workload 나 ssd, cpu 등의 Docker Host spec에 따라서 Container 배치가 가능
GCP / AWS / OpenStack 등에서 구축할 ���우, availability zone 등의 부가 정보로 간단히 multi region 에 container 배치 가능
기본적으로 CPU, Memory 등의 자원 상황에 따라 scaling
자원 부족 등의 경우 Kubernetes cluster auto scaling 이용 가능
container process 감시
container process 가 멈추면 self healing
HTTP/TCP, Shell Script 등을 이용한 Health Check 도 가능
특정 Container 군에 대해 Load Balancing 적용 가능
기능별로 세분화된 micro service architecture 에 필요한 service discovery 가능
Container 와 Service 의 데이터는 Backend 의 etcd 에 보존
Container 에서 공통적으로 설정이나 Application 에서 사용하는 데이터베이스의 암호 등의 정보를 Kubernetes Cluster 에서 중앙 관리 가능
Kubernetes 를 지원
Ansible : Deploy container to Kubernetes
Apache Ignite : Kubernetes 의 Service Discovery 기능을 이용한 자동 cluster 구성과 scaling
Fluentd : Kubernetes 상의 Container Log 를 전송
Jenkins : Deploy container to Kubernetes
OpenStack : Cloud 와 연계된 Kubernetes 구축
Prometheus : Kubernetes 감시
Spark : job 을 Kubernetes 상에서 Native 실행 (YARN 대체)
Spinnaker : Deploy container to Kubernetes
etc…
Kubernetes 에는 기능 확장이 가능하도록 되어 있어 독자적인 기능을 구현하는 것도 가능
Kubernetes 구축 환경 선택
개인 Windows / Mac 상에 로컬 Kubernetes 환경을 구축
구축 툴을 사용한 cluster 구축
public cloud 의 managed Kubernetes 를 이용
환경에 따라서 일부 이용 불가한 기능도 있으나 기본적으로 어떤 환경에서도 동일한 동작이 가능하도록 CNCF 가 Conformance Program 을 제공
Local Kubernetes
Minikube
VirtualBox 필요 (xhyve, VMware Fusion 도 이용 가능)
Homebrew 등을 이용한 설치 가능
Install
`$ brew update $ brew install kubectl $ brew cask install virtualbox $ brew install minikube `
Run
minikube 기동 시, 필요에 따라 kubernetes 버전을 지정 가능 --kubernetes-version
`$ minikube start —kubernetes-version v1.8.0 `
Minikube 용으로 VirtualBox 상에 VM 가 기동될 것이고 kubectl 로 Minikube 의 클러스터를 조작하는 것이 가능
상태 확인
`$ minikube status `
Minikube cluster 삭제
`$ minikube delete `
Docker for Mac
DockerCon EU 17 에 Docker 사에서 Kubernetes support 발표
Kubernetes 의 CLI 등에서 Docker Swarm 을 조작하는 등의 연계 기능 강화
17.12 CE Edge 버전부터 로컬에 Kubernetes 를 기동하는 것이 가능
Kubernetes 버전 지정은 불가
Docker for Mac 설정에서 Enable Kubernetes 지정
이후 kubectl 로 cluster 조작 가능
`$ kubectl config use-context docker-for-desktop `
kubectl 상에선 Docker Host 가 node로 인식
`$ kubectl get nodes `
Kubernetes 관련 component가 container 로서 기동
`$ docker ps --format 'table {{.Image}}\t{{.Command}}' | grep -v pause `
Kubernetes 구축 Tool
kubeadm
Kubernetes 가 공식적으로 제공하는 구축 도구
여기서는 Ubuntu 16.04 기준으로 기록 (환경 및 필요 버전에 따라 일부 변경 필요함)
준비
`apt-get update && apt-get install -y apt-transport-https curl -s https://package.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - cat </etc/aptsources.list.d/kubernetes.list deb http://apt.kubernetes.io/ kubernetes-xenial main EOF apt-get update apt-get install -y kubelet=1.8.5-00 kubeadm=1.8.5-00 kubectl=1.8.5-00 docker.io sysctl net.bridge.bridge-nf-call-iptables=1 `
Master node 를 위한 설정
--pod-network-cidr은 cluster 내 network (pod network) 용으로 Flannel을 이용하기 위한 설정
`$ kubeadm init --pod-network-cidr=10.244.0.0/16 `
위 설정 명령으로 마지막에 Kubernetes node 를 실행하기 위한 명령어가 출력되며 이후 node 추가시에 실행한다.
`$ kubeadm join --token ... 10.240.0.7:6443 --discovery-token-ca-cert-hash sha256:... `
kubectl 에서 사용할 인증 파일 준비
`$ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config `
Flannel deamon container 기동
`$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml `
Flannel 이 외에도 다른 선택이 가능 Installing a pod network add-on
Rancher
Rancher Labs 사
Open Source Container Platform
version 1.0 에서는 Kubernetes 도 서포트 하는 형식
version 2.0 부터는 Kubernetes 를 메인으로
Kubernetes cluster 를 다양한 플랫폼에서 가능 (AWS, OpenStack, VMware etc..)
기존의 Kubernetes cluster 를 Rancher 관리로 전환 가능
중앙집중적인 인증, 모니터링, WebUI 등의 기능을 제공
풍부한 Application Catalog
Rancher Server 기동
`docker run -d --restart=unless-stopped -p 8080:8080 rancher/server:v2.0.0-alpha10 `
이 Rancher Server 에서 각 Kubernetes cluster 의 관리와 cloud provider 연계 등을 수행
etc
Techtonic (CoreOS)
Kubespray
kops
OpenStack Magnum
Public Cloud managed Kubernetes
GKE (Google Kubernetes Engine)
많은 편리한 기능을 제공
GCP (Google Cloud Platform) 와 Integration.
HTTP LoadBalancer (Ingress) 사용 가능
NodePool
GUI or gcloud 명령어 사용
cluster version 간단 update
GCE (Google Compute Engine) 를 사용한 cluster 구축 가능
Container 를 사용하여 Kubernetes 노드가 재생성되어도 서비스에 영향을 미치지 않게 설계 가능
Kubernetes cluster 내부의 node 에 label 을 붙여 Group 화 가능
Group 화 하여 Scheduling 에 이용 가능
cloud 명령어로 cluster 구축
`$ gcloud container clusters create example-cluster `
인증 정보 저장
`$ gcloud container clusters get-credentials example-cluster `
etc
Google Kubernetes Engine
AKS (Azure Container Service)
Azure Container Service
EKS (Elastic Container Service for Kubernetes)
Amazon EKS
Kubernetes 기초
Kubernetes 는 실제로 Docker 이외의 container runtime 을 이용한 host 도 관리할 수 있도록 되어 있다. Kubernetes = Kubernetes Master + Kubernetes Node
Kubernetes Master
Kubernetes Node
API endpoint 제공
container scheduling
container scaling
Docker Host 처럼 실제로 container 가 동작하는 host
Kubernetes cluster 를 조작할 땐, CLI tool 인 kubectl 과 YAML 형식 manifest file 을 사용하여 Kubernetes Master 에 resource 등록 kubectl 도 내부적으로는 Kubernetes Master API 를 사용 = Library, curl 등을 이용한 조작도 가능
Kubernetes & Resource
resource 를 등록하면 비동기로 container 실행과 load balancer 작성된다. Resource 종류에 따라 YAML manifest 에 사용되는 parameter 가 상이
Kubernetes API Reference Docs
Kubernetes Resource
Workloads : container 실행에 관련
Discovery & LB : container 외부 공개 같은 endpoint를 제공
Config & Storage : 설정, 기밀정보, Persistent volume 등에 관련
Cluster : security & quota 등에 관련
Metadata : resource 조작
Workloads
cluster 상의 container 를 기동하기 위해 이용 내부적으로 이용하는 것을 제외한 이용자가 직접 이용하는 것으로는 다음과 같은 종류
Pod
ReplicationController
ReplicaSet
Deployment
DaemonSet
StatefulSet
Job
CronJob
Discovery & LB
container 의 service discovery, endpoint 등을 제공 내부적으로 이용하는 것을 제외한 이용자가 직접 이용하는 것으로는 다음과 같은 종류
Service : endpoint 의 제공방식에 따라 복수의 타입이 존재
Ingress
ClusterIP
NodePort
LoadBalancer
ExternalIP
ExternalName
Haedless
Config & Storage
설정이나 기밀 데이터 등을 container 에 넣거나 Persistent volume을 제공
Secret
ConfigMap
PersistentVolumeClaim Secret 과 ConfigMap 은 key-value 형식의 데이터 구조
Cluster
cluster 의 동작을 정의
Namespace
ServiceAccount
Role
ClusterRole
RoleBinding
ClusterRoleBinding
NetworkPolicy
ResourceQuota
PersistentVolume
Node
Metadata
cluster 내부의 다른 resource 동작을 제어
CustomResourceDefinition
LimitRange
HorizontalPodAutoscaler
Namespace 에 따른 가상 cluster 의 분리
Kubernetes 가상 cluster 분리 기능 (완전 분리는 아님) 하나의 Kubernetes cluster 를 복수 팀에서 이용 가능하게 함 Kubernetes cluster 는 RBAC (Role-Based Access Control) 이 기본 설정으로 Namesapce 를 대상으로 권한 설정을 할 수 있어 분리성을 높이는 것이 가능
초기 상태의 3가지 Namespace
default
kube-system : Kubernetes cluster 의 component와 addon 관련
kube-public : 모두가 사용 가능한 ConfigMap 등을 배치
CLI tool kubectl & 인증 정보
kubectl 이 Kubernetes Master 와 통신하기 위해 접속 서버의 정보와 인증 정보 등이 필요. 기본으로는 `~/.kube/config` 에 기록된 정보를 이용 `~/.kube/config` 도 YAML Manifest `~/.kube/config` example <pre>`apiVersion: v1 kind: Config preferences: {} clusters: - name: sample-cluster cluster: server: https://localhost:6443 users: - name: sample-user user: client-certificate-data: agllk5ksdgls2... client-key-data: aglk14l1t1ok15... contexts: - name: sample-context context: cluster: sample-cluster namespace: default user: sample-user current-context: sample-context `</pre>
`~/.kube/config` 에는 기본적으로 cluster, user, context 3가지를 정의 cluster : 접속하기 위한 cluster 정보 user : 인증 정보 context : cluster 와 user 페어에 namespace 지정 kubectl 를 사용한 설정 <pre>`# 클러스터 정의 $ kubectl config set-cluster prd-cluster --server=https://localhost:6443 # 인증정보 정의 $ kubectl config set-credentials admin-user \ --client-certificate \ --client-key=./sample.key \ --embed-certs=true # context(cluster, 인증정보, Namespace 정의) $ kubectl config --set-context prd-admin \ --cluster=prd-cluster \ --user=admin-user \ --namespace=default `</pre>
context 를 전환하는 것으로 복수의 cluster 와 user 를 사용하는 것이 가능
`# context 전환 $ kubectx prd-admin Switched to context "prd-admin". # namespace 전환 $ kubens kube-system Context "prd-admin" is modified. Active Namespace is "kube-system". `
## kubectl & YAML Manifest YAML Manifest 를 사용한 container 기동
pod 작성
`# sample-pod.yml apiVersion: vi kind: Pod metadata: name: sample-pod spec: containers: - name: nginx-container image: nginx:1.12 `
resource 작성
`# create resource $ kubectl create -f sample-pod.yml `
resource 삭제
`# delete resource $ kubectl delete -f sample-pod.yml `
resource update
`# apply 외 set, replace, edit 등도 사용 가능 $ kubectl apply -f sample-pod.yml `
## kubectl 사용법
resource 목록 획득 (get)
`$ kubectl get pods # 획득한 목록 상세 출력 $ kubectl get pods -o wide `
-o, —output 옵션을 사용하여 JSON / YAML / custom-columns / Go Template 등 다양한 형식으로 출력하는 것이 가능. 그리고 상세한 정보까지 확인 가능. pods 를 all 로 바꾸면 모든 리소스 일람 획득
resource 상세 정보 확인 (describe)
`$ kubectl describe pods sample-pod $ kubectl describe node k15l1 `
get 명령어 보다 resource 에 관련한 이벤트나 더 상세한 정보를 확인 가능
로그 확인 (logs)
`# Pod 내 container 의 로그 출력 $ kubectl logs sample-pod # 복수 container 가 포함된 Pod 에서 특정 container 의 로그 출력 $ kubectl logs sample-pod -c nginx-container # log follow option -f $ kubectl logs -f sample-pod # 최근 1시간, 10건, timestamp 표시 $ kubectl logs --since=1h --tail=10 --timestamp=true sample-pod `
Pod 상의 특정 명령 실행 (exec)
`# Pod 내 container 에서 /bin/sh $ kubectl exec -it sample-pod /bin/sh # 복수 container 가 포함된 Pod 의 특정 container 에서 /bin/sh $ kubectl exec -it sample-pod -c nginx-container /bin/sh # 인수가 있는 명령어의 경우, -- 이후에 기재 $ kubectl exec -it sample-pod -- /bin/ls -l / `
port-forward
`# localhost:8888 로 들어오는 데이터를 Pod의 80 포트로 전송 $ kubectl port-forward sample-pod 8888:80 # 이후 localhost:8888 을 통해 Pod의 80 포트로 접근 가능 $ curl localhost:8888 `
shell completion
`# bash $ source <(kubectl completion bash) # zsh completion $ source <(kubectl completion zsh) `
## Kubernetes Workloads Resource ## Workloads Resource
cluster 상에서 container 를 기동하기 위해 이용
8 종류의 resource 존재
Pod
ReplicationController
ReplicaSet
Deployment
DaemonSet
StatefulSet
Job
CronJob
디버그, 확인 용도로 주로 이용
ReplicaSet 사용 추천
Pod 을 scale 관리
scale 관리할 workload 에서 기본적으로 사용 추천
각 노드에 1 Pod 씩 배치
Persistent Data 나 stateful 한 workload 의 경우 사용
work queue & task 등의 container 종료가 필요한 workload 에 사용
정기적으로 Job을 수행
Pod
Kubernetes Workloads Resource 의 최소단위
1개 이상의 container 로 구성
Pod 단위로 IP Address 가 할당
대부분의 경우 하나의 Pod은 하나의 container 를 포함하는 경우가 대부분
proxy, local cache, dynamic configure, ssh 등의 보조 역할을 하는 container 를 같이 포함 하는 경우도 있다.
같은 Pod 에 속한 container 들은 같은 IP Address
container 들은 localhost 로 서로 통신 가능
Network Namespace 는 Pod 내에서 공유
보조하는 sub container 를 side car 라고 부르기도 한다.
Pod 작성
sample pod 을 작성하는 pod_sample.ymlapiVersion: v1 kind: Pod metadata: name: sample-pod spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80
nginx:1.12 image를 사용한 container 가 하나에 80 포트를 개방
설정 파일을 기반으로 Pod 작성
`$ kubectl apply -f ./pod_sample.yml `
기동한 Pod 확인
`$ kubectl get pods # 보다 자세한 정보 출력 $ kubectl get pods --output wide `
**2 개의 container 를 포함한 Pod 작성**
2pod_sample.yml
`apiVersion: v1 kind: Pod metadata: name: sample-2pod spec: containers: - name: nginx-container-112 image: nginx:1.12 ports: - containerPort: 80 - name: nginx-container-113 image: nginx:1.13 ports: - containerPort: 8080 `
**container 내부 진입**
container 의 bash 등을 실행하여 진입
`$ kubectl exec -it sample-pod /bin/bash `
-t : 모의 단말 생성
-i : 표준입력 pass through
ReplicaSet / ReplicationController
Pod 의 replica 를 생성하여 지정한 수의 Pod을 유지하는 resource
초창기 ReplicationController 였으나 ReplicaSet 으로 후에 변경됨
ReplicationController 는 equality-based selector 이용. 폐지 예정.
ReplicaSet 은 set-based selector 이용. 기본적으로 이를 이용할 것.
ReplicaSet 작성
sample ReplicaSet 작성 (rs_sample.yml)
`apiVersion: apps/v1 kind: ReplicaSet metadata: name: sample-rs spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80 `
ReplicaSet 작성
`$ kubectl apply -f ./rs_sample.yml `
ReplicaSet 확인
`$ kubectl get rs -o wide `
Label 지정하여 Pod 확인
`$ kubectl get pod -l app=sample-app -o wide `
**Pod 정지 & auto healing**
auto healing = ReplicaSet 은 node 나 pod 에 장애가 발생해도 pod 수를 지정한 수만큼 유지되도록 별도의 node 에 container 를 기동해주기에 장애에 대비하여 영향을 최소화할 수 있도록 가능하다.
Pod 삭제
`$ kubectl delete pod sample-rs-7r6sr `
Pod 삭제 후 다시 Pod 확인 하면 ReplicaSet 이 새로 Pod 이 생성된 것을 확인 가능
ReplicaSet 의 Pod 증감은 kubectl describe rs 명령어로 이력을 확인 가능
Label & ReplicaSet
ReplicaSet 은 Kubernetes 가 Pod 을 감시하여 수를 조정
감시하기 위한 Pod Label 은 spec.selector 에서 지정
특정 라벨이 붙은 Pod 의 수를 세는 것으로 감시
부족하면 생성, 초과하면 삭제
`selector: matchLabels: app: sample-app `
생성되는 Pod Label 은 labels 에 정의.
spec.template.metadata.labels 의 부분에도 app:sample-app 식으로 설정이 들어가서 Label 가 부여된 상태로 Pod 이 생성됨.
`labels: app: sample-app `
spec.selector 와 spec.template.metadata.labels 가 일치하지 않으면 Pod 이 끝없이 생성되다가 에러가 발생하게 될 것…
ReplicaSet 을 이용하지 않고 외부에서 별도로 동일한 label 을 사용하는 Pod 을 띄우면 초과한 수만큼의 Pod 을 삭제하게 된다. 이 때, 어느 Pod 이 지워지게 될지는 알 수 없으므로 주의가 필요
하나의 container 에 복수 label 을 부여하는 것도 가능
`labels: env: dev codename: system_a role: web-front `
**Pod scaling**
yaml config 을 수정하여 kubectl apply -f FILENAME 을 실행하여 변경된 설정 적용
kubectl scale 명령어로 scale 처리
scale 명령어로 처리 가능한 대상은
Deployment
Job
ReplicaSet
ReplicationController
`$ kubectl scale rs sample-rs --replicas 5 `
## Deployment
복수의 ReplicaSet 을 관리하여 rolling update 와 roll-back 등을 실행 가능
방식
전환 방식
Kubernetes 에서 가장 추천하는 container 의 기동 방법
새로운 ReplicaSet 을 작성
새로운 ReplicaSet 상의 Replica count 를 증가시킴
오래된 ReplicaSet 상의 Replica count 를 감소시킴
2, 3 을 반복
새로운 ReplicaSet 상에서 container 가 기동하는지, health check를 통과하는지 확인하면서
ReplicaSet 을 이행할 때의 Pod 수의 상세 지정이 가능
Deployment 작성
deployment_sample.yml
`apiVersion: apps/v1 kind: Deployment metadata: name: sample-deployment spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80 `
deployment 작성
`# record 옵션을 사용하여 update 시 이력을 보존 가능 $ kubectl apply -f ./deployment_sample.yml --record `
이력은 metadata.annotations.kubernetes.io/change-cause에 보존
현재 ReplicaSet 의 Revision 번호는 metadata.annotations.deployment.kubernetes.io/revision에서 확인 가능
`$ kubectl get rs -o yaml | head `
kubectl run 으로 거의 같은 deployment 를 생성하는 것도 가능
다만 default label run:sample-deployment 가 부여되는 차이 정도
`$ kubectl run sample-deployment --image nginx:1.12 --replicas 3 --port 80 `
deployment 확인
`$ kubectl get deployment $ kubectl get rs $ kubectl get pods `
container update
`# nginx container iamge 버전을 변경 $ kubectl set image deployment sample-deployment nginx-container=nginx:1.13 `
**Deployment update condition**
Deployment 에서 변경이 있으면 ReplicaSet 이 생성된다.
replica 수는 변경 사항 대상에 포함되지 않는다
생성되는 Pod 의 내용 변경이 대상
spec.template 의 변경이 있으면 ReplicaSet 을 신규 생성하여 rolling update 수행
spec.template이하의 구조체 해쉬값을 계산하여 그것을 이용해 label 을 붙이고 관리를 한다.
`# Deployment using hash value $ kubectl get rs sample-deployment-xxx -o yaml `
**Roll-back**
ReplicaSet 은 기본적으로 이력으로서 형태가 남고 replica 수를 0으로 하고 있다.
변경 이력 확인 kubectl rollout history
`$ kubectl rollout history deployment sample-deployment `
deployment 작성 시 —record 를 사용하면 CHANGE_CAUSE 부분의 값도 존재
roll-back 시 revision 값 지정 가능. 미지정시 하��� 전 revision 사용.
`# 한 단계 전 revision (default --to-revision = 0) $ kubectl rollout undo deployment sample-deployment # revision 지정 $ kubectl rollout undo deployment sample-deployment --to-revision 1 `
roll-back 기능보다 이전 YAML 파일을 kubectl apply로 적용하는게 더 편할 수 있음.
spec.template을 같은 걸로 돌리면 Template Hash 도 동일하여 kubectl rollout 과 동일한 동작을 수행하게 된다.
Deployment Scaling
ReplicaSets 와 동일한 방법으로 kubectl scale or kubectl apply -f을 사용하여 scaling 가능
보다 고급진 update 방법
recreate 라는 방식이 존재
DaemonSet
ReplicaSet 의 특수한 형식
모든 Node 에 1 pod 씩 배치
모든 Node 에서 반드시 실행되어야 하는 process 를 위해 이용
replica 수 지정 불가
2 pod 씩 배치 불가
ReplicaSet 은 각 Kubernetes Node 상에 상황에 따라 Pod 을 배치하는 것이기에 균등하게 배포된다는 보장이 없다.
DaemonSet 작성
ds_sample.yml
`apiVersion: apps/v1 kind: DaemonSet metadata: name: sample-ds spec: selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80 `
DaemonSet 작성
`$ kubectl apply -f ./ds_sample.yml `
확인
`$ kubectl get pods -o wide `
## StatefulSet
ReplicaSet 의 특수한 형태
database 처럼 stateful 한 workloads 에 대응하기 위함
생성되는 Pod 명이 숫자로 indexing
persistent 성
sample-statefulset-1, sample-statefulset-2, …
PersistentVolume을 사용하는 경우 같은 disk 를 이용하여 재작성
Pod 명이 바뀌지 않음
StatefulSet 작성
spec.volumeClaimTemplates 지정 가능
statefulset-sample.yml
persistent data 영역을 재사용하여 pod 이 복귀했을 때 동일 데이터를 사용하여 container 가 작성되도록 가능
`apiVersion: apps/v1 kind: StatefulSet metadata: name: sample-statefulset spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80 volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi `
StatefulSet 작성
`$ kubectl apply -f ./statefulset_sample.yml `
확인 (ReplicaSet 과 거의 동일한 정보)
`$ kubectl get statefulset # Pod 이름에 연속된 수로 index 가 suffix 된 것을 확인 $ kubectl get pods -o wide `
scale out 시 0, 1, 2 의 순으로 만들어짐
scale in 시 2, 1, 0 의 순으로 삭제
StatefulSet Scaling
ReplicaSets 와 동일 kubectl scale or kubectl apply -f
Persistent 영역 data 보존 확인
`$ kubectl exec -it sample-statefulset-0 ls /usr/share/nginx/html/sample.html ls: cannot access /usr/share/nginx/html/sample.html: No such file or directory $ kubectl exec -it sample-statefulset-0 touch /usr/share/nginx/html/sample.html $ kubectl exec -it sample-statefulset-0 ls /usr/share/nginx/html/sample.html /usr/share/nginx/html/sample.html `
kubectl 로 Pod 삭제를 하던지 container 내부에서 Exception 등이 발생하는 등으로 container 가 정지해도 file 이 사라지지 않는다.
Pod 명이 바뀌지 않아도 IP Address 는 바뀔 수 있다.
Life Cycle
ReplicaSet 과 다르게 복수의 Pod 을 병렬로 생성하지 않고 1개씩 생성하여 Ready 상태가 되면 다음 Pod 을 작성한다.
삭제 시, index 가 가능 큰 (최신) container 부터 삭제
index:0 이 Master 가 되도록 구성을 짤 수 있다.
Job
container 를 이용하여 일회성 처리를 수행
병렬 실행이 가능하면서 지정한 횟수만큼 container 를 실행 (정상종료) 하는 것을 보장
Job 을 이용 가능한 경우와 Pod 과의 차이
Pod 이 정지하는 것을 전제로 만들어져 있는가?
Pod, ReplicaSets 에서 정지=예상치 못한 에러
Job 은 정지=정상종료
patch 등의 처리에 적합
Job 작성
job_sample.yml : 60초 sleep
ReplicaSets 와 동일하게 label 과 selector 를 지정가능하지만 kubernetes 에서 자동으로 충돌하지 않도록 uuid 를 자동 생성함으로 굳이 지정할 필요 없다.
`apiVersion: batch/v1 kind: Job metadata: name: sample-job spec: completions: 1 parallelism: 1 backoffLimit: 10 template: spec: containers: - name: sleep-container image: centos:latest command: ["sleep"] args: ["60"] restartPolicy: Never `
Job 작성
`$ kubectl apply -f job_sample.yml `
Job 확인
`$ kubectl get jobs $ kubectl get pods `
**restartPolicy**
spec.template.spec.restartPolicy 에는 OnFailure or Never 지정 가능
Never : 장애 시 신규 Pod 작성
OnFailure : 장애 시 동일 Pod 이용하여 Job 재개 (restart count 가 올라간다)
Parallel Job & work queue
completions : 실행 횟수
parallelism : 병렬수
backoffLimit : 실패 허용 횟수. 미지정 시 6
1개씩 work queue 형태로 실행할 경우 completions 를 미지정
parallelism만 지정하면 Persistent 하게 Job을 계속 실행
deployment 등과 동일하게 kubectl scale job… 명령으로 나중에 제어 하는 것도 가능
CronJob
ScheduledJob -> CronJob 으로 명칭 변경됨
Cron 처럼 scheduling 된 시간에 Job 을 생성
create CronJob
cronjob_sample.yml : 60초 마다 30초 sleep
`apiVersion: batch/v1beta1 kind: CronJob metadata: name: sample-cronjob spec: schedule: "*/1 * * * *" concurrencyPolicy: Forbid startingDeadlineSeconds: 30 successfulJobHistoryLimit: 5 failedJobsHistoryLimit: 5 jobTemplate: spec: template: spec: containers: - name: sleep-container image: centos:latest command: ["sleep"] args: ["30"] restartPolicy: Never `
create
`$ kubectl apply -f cronjob_sample.yml `
별도 설정없이 kubectl run —schedule 로 create 가능
`$ kubectl run sample-cronjob --schedule = "*/1 * * *" --restart Never --image centos:latest -- sleep 30 `
확인
`$ kubectl get cronjob $ kubectl get job `
**일시 정지**
spec.suspend 가 true 로 설정되어 있으면 schedule 대상에서 제외됨
YAML 을 변경한 후 kubectl apply
kubectl patch 명령어로도 가능
`$ kubectl patch cronjob sample-cronjob -p '{"spec":{"suspend":true}}' `
kubectl patch에서는 내부적으로 HTTP PATCH method 를 사용하여 Kubernetes 독자적인 Strategic Merge Patch 가 수행된다.
실제로 수행되는 request 를 확인하고 싶으면 -v (Verbose) 옵션 사용
`$ kubectl -v=10 patch cronjob sample-cronjob -p '{"spec":{"suspend":true}}' `
kubectl get cronjob 에서 SUSPEND 항목이 True 로 된 것을 확인
다시 scheduling 대상에 넣고 싶으면 spec.suspend 를 false 로 설정
동시 실행 제어
spec.concurrencyPolicy
spec.startingDeadlineSeconds : Kubernetes Master 가 일시적으로 동작 불가한 경우 등 Job 개시 시간이 늦어졌을 때 Job 을 개시 허용할 수 있는 시간(초)를 지정
spec.successfulJobsHistoryLimit : 보존하는 성공 Job 수.
spec.failedJobsHistoryLimit : 보존하는 실패 Job 수.
Allow (default) : 동시 실행과 관련 제어 하지 않음
Forbid : 이전 Job 이 종료되지 않았으면 새로운 Job 을 실행하지 않음.
Replace : 이전 Job 을 취소하고 새로운 Job 을 실행
300 의 경우, 지정된 시간 보다 5분 늦어도 실행 가능
기본으론 늦어진 시간과 관계없이 Job 생성 가능
default 3.
0 은 바로 삭제.
default 3.
0 은 바로 삭제
Discovery & LB resource
cluster 상의 container 에 접근할 수 있는 endpoint 제공과 label 이 일치하는 container 를 찾을 수 있게 해줌
2 종류가 존재
Service : Endpoint 의 제공방법이 다른 type 이 몇가지 존재
Ingress
ClusterIP
NodePort
LoadBalancer
ExternalIP
ExternalName
Headless (None)
Cluster 내 Network 와 Service
Kubernetes 에서 cluster 를 구축하면 Pod 을 위한 Internal 네트워크가 구성된다.
Internal Network 의 구성은 CNI (Common Network Interface) 라는 pluggable 한 module 에 따라 다르지만, 기본적으로는 Node 별로 상이한 network segment 를 가지게 되고, Node 간의 traffic 은 VXLAN 이나 L2 Routing 을 이용하여 전송된다.
Kubernetes cluster 에 할당된 Internal network segment 는 자동적으로 분할되어 node 별로 network segment 를 할당하기 때문에 의식할 필요 없이 공통의 internal network 를 이용 가능하다.
이러한 특징으로 기본적으로 container 간 통신이 가능하지만 Service 기능을 이용함으로써 얻을 수 있는 이점이 있다.
Pod 에 발생하는 traffic 의 load balancing
Service discovery & internal dns
위 2가지 이점은 모든 Service Type 에서 이용 가능
Pod Traffic 의 load balancing
Service 는 수신한 traffic을 복수의 Pod 에 load balancing 하는 기능을 제공
Endpoint 의 종류에는 cluster 내부에서 이용 가능한 VIP (Virtual IP Address) 와 외부의 load balancer 의 VIP 등 다양한 종류가 제공된다
example) deployment_sample.yml
Deployment 로 복수 Pod 이 생성되면 제각각 다른 IP Address 를 가지게 되는데 이대로는 부하분산을 이용할 수 없지만 Service 가 복수의 Pod 을 대상으로 load balancing 가능한 endpoint 를 제공한다.
`apiVersion: apps/v1 kind: Deployment metadata: name: sample-deployment spec: replicas: 3 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 ports: - containerPort: 80 `
`$ kubectl apply -f deployment_sample.yml `
Deployment 로 생성된 Pod 의 label 과 pod-template-hash 라벨을 사용한다.
`$ kubectl get pods sample-deployment-5d.. -o jsonpath='{.metadata.labels}' map[app:sample-app pod-template-hash:...]% `
전송할 Pod 은 spec.selector 를 사용하여 설정 (clusterip_sample.yml)
`apiVersion: v1 kind: Service metadata: name: sample-clusterip spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: sample-app `
`$ kubectl apply -f clusterip_sample.yml `
Service 를 만들면 상세정보의 Endpoint 부분에 복수의 IP Address 와 Port 가 표시된다. 이는 selector 에 지정된 조건에 매칭된 Pod 의 IP Address 와 Port.
`$ kubectl describe svc sample-clusterip `
Pod 의 IP 를 비교하기 위해 특정 JSON path 를 column 으로 출력
`$ kubectl get pods -l app=sample-app -o custom-columns="NAME:{metadata.name},IP:{status.podIP}" `
load balancing 확인을 쉽게 위해 테스트로 각 pod 상의 index.html 을 변경.
Pod 의 이름을 획득하고 각각의 pod 의 hostname 을 획득한 것을 index.html 에 기록
`for PODNAME in `kubectl get pods -l app=sample-app -o jsonpath='{.items[*].metadata.name}'`; do kubectl exec -it ${PODNAME} -- sh -c "hostname > /usr/share/nginx/html/index.html"; done `
일시적으로 Pod 을 기동하여 Service 의 endpoint 로 request
`$ kubectl run --image=centos:7 --restart=Never --rm -i testpod -- curl -s http://[load balancer ip]:[port] `
**Service Discovery 와 Internal DNS**
Service Discovery
Service Discovery 방법
Service 가 제공
특정 조건의 대상이 되는 member 를 열거하거나, 이름으로 endpoint 를 판별
Service 에 속하는 Pod 을 열거하거나 Service 이름으로 endpoint 정보를 반환
A record 를 이용
SRV record 를 이용
환경변수를 이용
A record 를 이용한 Service Discovery
Service 를 만들면 DNS record 가 자동적으로 등록된다
내부적으로는 kube-dns 라는 system component가 endpoint 를 대상으로 DNS record를 생성
Service 를 이용하여 DNS 명을 사용할 수 있으면 IP Address 관련한 관리나 설정을 신경쓰지 않아도 되기 때문에 이를 사용하는 것이 편리
`# IP 대신에 sample-clusterip 라는 Service 명을 이용 가능 $ kubectl run --image=centos:7 --restart=Never --rm -i testpod -- curl -s http://sample-clusterip:8080 `
실제로 kube-dns 에 등록되는 정식 FQDN 은 [Service name].[Namespace name].svc.[ClusterDomain name]
`# container 내부에서 sample-clusterip.default.svc.cluster.local 를 조회 $ kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig sample-clusterip.default.svc.cluster.local `
FQDN 에서는 Service 충돌을 방지하기 위해 Namespace 등이 포함되어 있으나 container 내부의 /etc/resolv.conf 에 간략한 domain 이 지정되어 있어 실제로는 sample-clusterip.default 나 sample-clusterip 만으로도 조회가 가능하다.
IP 로도 FQDN 을 반대로 조회하는 것도 가능
`$ kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig -x 10.11.245.11 `
**SRV record 를 이용한 Service Discovery**
[_Service Port name].[_Protocol].[Service name].[Namespace name].svc.[ClusterDomain name]의 형식으로도 확인 가능
`$ kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig _http-port._tcp.sample-clusterip.default.svc.cluster.local SRV `
**환경변수를 이용한 Service Discovery**
Pod 내부에서는 환경변수로도 같은 Namespace 의 서비스가 확인 가능하도록 되어 있다.
‘-‘ 가 포함된 서비스 이름은 ‘_’ 로, 그리고 대문자로 변환된다.
docker --links ...와 같은 형식으로 환경변수가 보존
container 기동 후에 Service 추가나 삭제에 따라 환경변수가 갱신되는 것은 아니라서 예상 못한 사고가 발생할 가능성도 있다.
Service 보다 Pod 이 먼저 생성된 경우에는 환경변수가 등록되어 있지 않기에 Pod 을 재생성해야 한다.
Docker 만으로 이용하던 환경에서 이식할 때에도 편리
`$ kubectl exec -it sample-deployment-... env | grep -i sample_clusterip `
**복수 port 를 사용하는 Service 와 Service Discovery**
clusterip_multi_sample.yml
`apiVersion: v1 kind: Service metadata: name: sample-clusterip spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 - name: "https-port" protocol: "TCP" port: 8443 targetPort: 443 selector: app: sample-app `
## ClusterIP
가장 기본
Kubernetes cluster 내부에서만 접근 가능한 Internal Network 의 VIP 가 할당된다
ClusterIP 로의 통신은 node 상에서 동작하는 system component 인 kube-proxy가 Pod을 대상으로 전송한다. (Proxy-mode 에 따라 상이)
Kubernetes cluster 외부에서의 접근이 필요없는 곳에 이용한다
기본으로는 Kubernetes API 에 접속하기 위한 Service 가 만들어져 있고 ClusterIP 가 를 사용한다.
`# TYPE 의 ClusterIP 확인 $ kubectl get svc `
**create ClusterIP Service**
clusterip_sample.yml
`apiVersion: v1 kind: Service metadata: name: sample-clusterip spec: type: ClusterIP ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: sample-app `
type: ClusterIP 지정
spec.ports[x].port 에는 ClusterIP로 수신하는 Port 번호
spec.ports[x].targetPort 는 전달할 container 의 Port 번호
Static ClusterIP VIP 지정
database 를 이용하는 등 기본적으로는 Kubernetes Service에 등록된 내부 DNS record를 이용하여 host 지정하는 것을 추천
수동으로 지정할 경우 spec.clusterIP를 지정 (clusterip_vip_sample.yml)
`apiVersion: v1 kind: Service metadata: name: sample-clusterip spec: type: ClusterIP clusterIP: 10.11.111.11 ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: sample-app `
이미 ClusterIP Service가 생성되어 있는 상태에서는 ClusterIP 를 변경할 수 없다.
kubectl apply 로도 불가능
먼저 생성된 Service 를 삭제해야 한다.
ExternalIP
특정 Kubernetes Node 의 IP:Port 로 수신한 traffic 을 container 로 전달하는 방식으로 외부와 연결
create ExternalIP Service
externalip_sample.yml
`apiVersion: v1 kind: Service metadata: name: sample-externalip spec: type: ClusterIP externalIPs: - 10.1.0.7 - 10.1.0.8 ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 selector: app: sample-app `
type: ExternalIP 가 아닌 type: ClusterIP 인 것에 주의
spec.ports[x].port 는 ClusterIP 로 수신하는 Port
spec.ports[x].targetPort 는 전달할 container 의 Port
모든 Kubernetes Node 를 지정할 필요는 없음
ExternalIP 에 이용 가능한 IP Address 는 node 정보에서 확인
GKE 는 OS 상에서는 global IP Address가 인식되어 있지 않아서 이용 불가
`# IP address 확인 $ kubectl get node -o custom-columns="NAME:{metadata.name},IP:{status.addresses[].address}" `
ExternalIP Service 를 생성해도 container 내부에서 사용할 ClusterIP 도 자동적으로 할당된다.
container 안에서 DNS로 ExternalIP Service 확인
`$ kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig sample-externalip.default.svc.cluster.local `
ExternalIP 를 이용하는 node 의 port 상태
`$ ss -napt | grep 8080 `
ExternalIP 를 사용하면 Kubernetes cluster 밖에서도 접근이 가능하고 또한 Pod 에 분산된다.
NodePort
모든 Kubernetes Node 의 IP:Port 에서 수신한 traffic 을 container 에 전송
ExternalIP Service 의 모든 Node 버전 비슷한 느낌
Docker Swarm 의 Service 를 Expose 한 경우와 비슷
create NodePort Service
nodeport_sample.yml
`apiVersion: v1 kind: Service metadata: name: sample-nodeport spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30080 selector: app: sample-app `
spec.ports[x].port 는 ClusterIP 로 수신하는 Port
spec.ports[x].targetPort 는 전달할 container Port
spec.ports[x].nodePort 는 모든 Kubernetes Node 에서 수신할 Port
container 안에서 통신에 사용할 ClusterIP 도 자동적으로 할당된다
지정하지 않으면 자동으로 비어있는 번호를 사용
Kubernetes 기본으로는 이용할 수 있는 번호가 30000~32767
복수의 NodePort 가 동일 Port 사용 불가
Kubernetes Master 설정에서 변경 가능
`$ kubectl get svc `
container 안에서 확인하면 내부 DNS 가 반환하는 IP Address 는 External IP 가 아닌 Cluster IP
`$ kubectl run --image=centos:6 --restart=Never --rm -i testpod -- dig sample-nodeport.default.svc.cluster.local `
Kubernetes Node 상에서 Port 상태를 확인하면 nodePort 에 지정한 값으로 Listen
`$ ss -napt | grep 30080 `
ExternalIP 와 다르게 모든 Node 의 IP Address 로 Kubernetes Cluster 외부에서 접근 가능하며 Pod 으로의 request 도 분산된다.
GKE 도 GCE에 할당된 global IP Address 로 접근 가능
Node 간 통신의 배제 (Node 를 건넌 load balancing 배제)
NodePort 에서는 Node 상의 NodePort 에 도달한 packet 은 Node 를 건너서도 load balancing 이 이루어진다
DaemonSet 등을 사용하면 각 Node에 1 Pod 이 존재하기에 같은 Node 상의 Pod 에만 전달하고 싶을 때 사용
spec.externalTrafficPolicy 를 사용하여 실현 가능
externalTrafficPolicy 를 Cluster 에서 Local 로 변경하기 위해선 YAML 이용 (nodeport_local_sample.yml)
Cluster (Default)
Local
Node 에 도달한 후 각 Node 에 load balancing
실제로는 kube-proxy 설정으로 iptables 의 proxy mode를 사용할 경우, 자신의 Node 에 좀 더 많이 전달되도록 되는 것으로 보여짐 (iptables-save 등으로 statistics 부분을 확인)
도달한 Node 에 속한 Pod 에 전달 (no load balancing)
만약 Pod 이 존재하지 않으면 Response 불가
만일 Pod 이 복수 존재한다면 균등하게 분배
`apiVersion: v1 kind: Service metadata: name: sample-nodeport-local spec: type: NodePort externalTrafficPolicy: Local ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30081 selector: app: sample-app `
## LoadBalancer
가장 사용성이 좋고 실용적
Kubernetes Cluster 외부의 LoadBalancer 에 VIP 를 할당 가능
NodePort 등에선 결국 Node 에 할당된 IP Address 에 endpoint 역할까지 담당시키는 것이라 SPoF (Single Point of Failure) 로 Node 장애에 약하다
외부의 load balancer 를 이용하는 것으로 Kubernetes Node 장애에 강하다
단 외부 LoadBalancer 와 연계 가능한 환경으로 GCP, AWS, Azure, OpenStack 등의 CloudProvider 에 한정된다 (이는 추후에 점차 확대될 수 있다)
NodePort Service 를 만들어서 Cluster 외부의 Load Balancer 에서 Kubernetes Node 에 balancing 한다는 느낌
create LoadBalancer Service
lb_sample.yml
`apiVersion: v1 kind: Service metadata: name: sample-lb spec: type: LoadBalancer ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30082 selector: app: sample-app `
spec.ports[x].port 는 LoadBalancer VIP 와 ClusterIP 로 수신하는 Port
spec.ports[x].targetPort 는 전달할 container Port
NodePort 도 자동적으로 할당됨으로 spec.ports[x].nodePort 의 지정도 가능
확인
`$ kubectl get svc sample-lb `
EXTERNAL-IP 가 pending 상태인 경우 LoadBalancer 가 준비되는데 시간이 필요한 경우
Container 내부 통신에는 Cluster IP 를 사용하기에 ClusterIP 도 자동할당
NodePort 도 생성
VIP 는 Kubernetes Node 에 분산되기 때문에 Kubernetes Node 의 scaling 시 변경할 것이 없다
Node 간 통신 배제 (Node 를 건넌 load balancing 배제)
NodePort 와 동일하게 externalTrafficPolicy 를 이용 가능
LoadBalancer VIP 지정
spec.LoadBalancerIP 로 외부의 LoadBalancer IP Address 지정 가능
`# lb_fixip_sample.yml apiVersion: v1 kind: Service metadata: name: sample-lb-fixip spec: type: LoadBalancer loadBalancerIP: xxx.xxx.xxx.xxx ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30083 selector: app: sample-app `
미지정 시 자동 할당
GKE 등의 cloud provider 의 경우 주의
GKE 에서는 LoadBalancer service 를 생성하면 GCLB 가 생성된다.
GCP LoadBalancer 등으로 비용이 증가 되지 않도록 주의
IP Address 중복이 허용되거나 deploy flow 상 문제가 없으면 가급적 Service 를 정리할 것
Service 를 만든 상태에서 GKE cluster 를 삭제하면 GCLB 가 과금 되는 상태로 남아버리므로 주의
Headless Service
Pod 의 IP Address 가 반환되는 Service
보통 Pod 의 IP Address 는 자주 변동될 수 있기 때문에 Persistent 한 StatefulSet 한정하여 사용 가능
IP endpoint 를 제공하는 것이 아닌 DNS Round Robin (DNS RR) 을 사용한 endpoint 제공
DNS RR 은 전달할 Pod 의 IP Address 가 cluster 안의 DNS 에서 반환되는 형태로 부하분산이 이루어지기에 client 쪽 cache 에 주의할 필요가 있다.
기본적으로 Kubernetes 는 Pod 의 IP Address 를 의식할 필요가 없도록 되어 있어서 Pod 의 IP Address 를 discovery 하기 위해서는 API 를 사용해야만 한다
Headless Service 를 이용하여 StatefulSet 한정으로 Service 경유로 IP Address 를 discovery 하는 것이 가능하다
create Headless Service
3가지 조건이 충족되어야 한다
Service 의 spec.type 이 ClusterIP
Service 의 metadata.name 이 StatefulSet 의 spec.serviceName 과 같을 것
Service 의 spec.clusterIP 가 None 일것
위 조건들이 충족되지 않으면 그냥 Service 로만 동작하고 Pod 이름을 얻는 등이 불가능하다.
`# headless_sample.yml apiVersion: v1 kind: Service metadata: name: sample-svc spec: type: ClusterIP clusterIP: None ports: - name: "http-port" protocol: "TCP" port: 80 targetPort: 80 selector: app: sample-app `
**Headless Service 를 이용한 Pod 이름 조회**
보통 Service 를 만들면 복수 Pod 에 대응하는 endpoint 가 만들어져 해당 endpoint. 에 대응하여 이름을 조회하는 것이 가능하지만 각각의 Pod 의 이름 조회는 불가능하다
보통 Service 의 이름 조회는 [Service name].[Namespace name].svc.[domain name] 로 조회가 가능하도록 되어 있지만 Headless Service 로 그대로 조회하면 DNS Round Robin 으로 Pod 중의 IP 가 반환되기에 부하 분산에는 적합하지 않다
StatefulSet 의 경우에만, [Pod name].[Service name].[Namespace name].svc.[domain name] 형식으로 Pod 이름 조회가 가능하다
container 의 resolv.conf 등에 search 로 entry 가 들어가 있다면 [Pod name].[Service name] 혹은 [Pod name].[Service name].[Namespace] 등으로 조회 가능
ReplicaSet 등의 Resource 에서도 가능
ExternalName
다른 Service 들과 다르게 Service 이름 조회에 대응하여 CNAME 을 반환하는 Service
주로 다른 이름을 설정하고 싶거나 cluster 안에서 endpoint 를 전환하기 쉽게 하고 싶을 때 사용
create ExternalName service
`# externalname_sample.yml apiVersion: v1 kind: Service metadata: name: sample-externalname namespace: default spec: type: ExternalName externalName: external.example.com `
`$ kubectl get svc `
EXTERNAL-IP 부분에 CNAME 용의 DNS 가 표시된다
container 내부에서 [Service name] 이나 [Service name].[Namespace name].svc.[domain name] 으로 조회하면 CNAME 가 돌아오는 것을 확인 가능
`$ dig sample-externalname.default.svc.cluster.local CNAME `
**Loosely Coupled with External Service**
Cluster 내부에서는 Pod 로의 통신에 Service 이름 조회를 사용하는 것으로 서비스 간의 Loosely Coupled 를 가지는 것이 가능했지만, SaaS 나 IaaS 등의 외부 서비스를 이용하는 경우에도 필요가 있다.
Application 등에서 외부 endpoint를 설정하면 전환할 때 Application 쪽 설정 변경이 필요해지는데 ExternalName을 이용하여 DNS 의 전환은 ExternalName Service 의 변경만으로 가능하여 Kubernetes 상에서 가능해지고 외부와 Kubernetes Cluster 사이의 Loosely Coupled 상태도 유지 가능하다.
외부 서비스와 내부 서비스 간의 전환
ExternalName 이용으로 외부 서비스와의 Loosely Coupled 확보하고 외부 서비스와 Kubernetes 상의 Cluster 내부 서비스의 전환도 유연하게 가능하다
Ingress
L7 LoadBalancer 를 제공하는 Resource
Kubernetes 의 Network Policy resource 에 Ingress/Egress 설정항목과 관련 없음
Ingress 종류
아직 Beta Service 일 가능성
크게 구분하여 2가지
Cluster 외부의 Load Balancer를 이용한 Ingress
Cluster 내부에 Ingress 용의 Pod 을 생성하여 이용하는 Ingress
GKE
Nginx Ingress
Nghttpx Ingress
Cluster 외부의 Load Balancer 를 이용한 Ingress
GKE 같은 Cluster 외부의 Load Balancer를 이용한 Ingress 의 경우, Ingress rosource 를 만드는 것만으로 LoadBalancer 의 VIP 가 만들어져 이용하는 것이 가능
GCP의 GCLB (Google Cloud Load Balancer) 에서 수신한 traffic을 GCLB 에서 HTTPS 종단이나 path base routing 등을 수행하여 NodePort에 traffic을 전송하는 것으로 대상 Pod 에 도달
Cluster 내부에 Ingress 용의 Pod 을 생성하여 이용하는 Ingress
L7 역할을 할 Pod을 Cluster 내부에 생성하는 형태로 실현
Cluster 외부에서 접근 가능하도록 별도 Ingress 용 Pod에 LoadBalancer Service를 작성하는 등의 준비가 필요하다
Ingress 용의 Pod 이 HTTPS 종단이나 path base routing 등의 L7 역할을 하기 위해 Pod 의 replica 수의 auto scale 등도 고려할 필요가 있다.
LB와 일단 Nginx Pod 에 전송하여 Nginx 가 L7 역할을 하여 처리한 후 대상 Pod 에 전송한다.
NodePort 경유하지 않고 직접 Pod IP 로 전송
create Ingress resource
사전 준비가 필요
사전에 만들어진 Service를 Back-end로서 활용하여 전송을 하는 형태
Back-end 로 이용할 Service 는 NodePort 를 지정
`# sample-ingress-apps apiVersion: apps/v1 kind: Deployment metadata: name: sample-ingress-apps spec: replicas: 1 selector: matchLabels: ingress-app: sample template: metadata: labels: ingress-app: sample spec: containers: - name: nginx-container image: zembutsu/docker-sample-nginx:1.0 ports: - containerPort: 80 `
`# ingress service sample apiVersion: v1 kind: Service metadata: name: svc1 spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 8888 targetPort: 80 selector: ingress-app: sample `
Ingress 로 HTTPS 를 이용하는 경우에는 인증서는 사전에 Secret 으로 등록해둘 필요가 있다.
Secret 은 인증서의 정보를 바탕으로 YAML 파일을 직접 만들거나 인증서 파일을 지정하여 만든다.
`# 인증서 작성 $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=sample.example.com" # Secret 작성 (인증서 파일을 지정하는 경우) $ kubectl create secret tls tls-sample --key /tmp/tls.key --cert /tmp/tls.crt `
Ingress resource 는 L7 Load Balancer 이기에 특정 host 명에 대해 request path > Service back-end 의 pair 로 전송 rule 을 설정한다.
하나의 IP Address 로 복수의 Host 명을 가지는 것이 가능하다.
spec.rules[].http.paths[].backend.servicePort 에 설정하는 Port 는 Service 의 spec.ports[].port 를 지정
`# ingress_sample.yml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: sample-ingress annotations: ingress.kubernetes.io/rewrite-target: / spec: rules: - host: sample.example.com http: paths: - path: /path1 backend: serviceName: svc1 servicePort: 8888 backend: serviceName: svc1 servicePort: 8888 tls: - hosts: - sample.example.com secretName: tls-sample `
**Ingress resource & Ingress Controller**
Ingress resource = YAML file 에 등록된 API resource
Ingress Controller = Ingress resource 가 Kubernetes 에 등록되었을 때, 어떠한 처리를 수행하는 것
GCP 의 GCLB 를 조작하여 L7 LoadBalancer 설정을 하는 것이나,
Nginx 의 Config 를 변경하여 reload 하는 등
GKE 의 경우
GKE 의 경우, 기본으로 GKE 용 Ingress Controller 가 deploy 되어 있어 딱히 의식할 필요 없이 Ingress resource 마다 자동으로 IP endpoint 가 만들어진다.
Nginx Ingress 의 경우
Nginx Ingress 를 이용하는 경우에는 Nginx Ingress Controller 를 작성해야 한다.
Ingress Controller 자체가 L7 역할을 하는 Pod 이 되기도 하기에 Controller 라는 이름이지만 실제 처리도 수행한다.
GKE 와 같이 cluster 외부에서도 접근을 허용하기 위해서는 Nginx Ingress Controller 으로의 LoadBalancer Service (NodePort 등도 가능) 를 작성할 필요가 있다.
개별적으로 Service 를 만드는 것이기에 kubectl get ingress 등으로 endpoint IP Address 를 확인 불가 하기에 주의가 필요하다.
rule 에 매칭되지 않을 경우의 default 로 전송할 곳을 작성할 필요가 있으니 주의
실제로는 RBAC, resource 제한, health check 간격 등 세세한 설정해 둬야 할 수 있다.
nginx ingress 추천 설정
`# Nginx ingress를 이용하는 YAML sample apiVersion: apps/v1 kind: Deployment metadata: name: default-http-backend labels: app: default-http-backend spec: replicas: 1 selector: matchLabels: app: default-http-backend template: metadata: labels: app: default-http-backend spec: containers: - name: default-http-backend image: gcr.io/google_containers/defaultbackend:1.4 livenessProbe: httpGet: path: /healthz port: 8080 scheme: HTTP ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: default-http-backend labels: app: default-http-backend spec: ports: - port: 80 targetPort: 8080 selector: app: default-http-backend --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-ingress-controller spec: replicas: 1 selector: matchLabels: app: ingress-nginx template: metadata: labels: app: ingress-nginx spec: containers: - name: nginx-ingress-controller image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.14.0 args: - /nginx-ingress-controller - --default-backend-service=$(POD_NAMESPACE)/default-http-backend env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: http containerPort: 80 - name: https containerPort: 443 livenessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP readinessProbe: httpGet: path: /healthz port: 10254 scheme: HTTP --- apiVersion: v1 kind: Service metadata: name: ingress-endpoint labels: app: ingress-nginx spec: type: LoadBalancer ports: - port: 80 targetPort: 8080 selector: app: ingress-nginx `
default back-end pod 이나 L7 처리할 Nginx Ingress Controller Pod 의 replica 수가 고정이면 traffic 이 늘었을 때 감당하지 못할 가능성도 있으니 Pod auto scaling 을 수행하는 Horizontal Pod Autoscaler (HPA) 의 이용도 검토해야 할 수 있음
deploy 한 Ingress Controller 는 cluster 상의 모든 Ingress resource 를 봐 버리기에 충돌할 가능성이 있다.
상세 사양
Ingress Class 를 이용하여 처리하는 대상 Ingress resource 를 분리하는 것이 가능
Ingress resource 에 Ingress Class Annotation 을 부여하여 Nginx Ingress Controller 에 대상으로 하는 Ingress Class를 설정하는 것으로 대상 분리 가능
Nginx Ingress Controller 의 기동 시 --ingress-class 옵션 부여
Ingress resource Annotation
/nginx-ingress-controller --ingress-class=system_a ...
kubernetes.io/ingress.class: "system_a"
정리
Kubernetes Service & Ingress
Service
Ingress
L4 Load Balancing
Cluster 내부 DNS 로 lookup
label 을 이용한 Pod Service Discovery
L7 Load Balancing
HTTPS 종단
path base routing
Kubernetes Service
ClusterIP : Kubernetes Cluster 내부 한정으로 통신 가능한 VIP
ExternalIP : 특정 Kubernetes Node 의 IP
NodePort : 모든 Kubernetes Node 의 모든 IP (0.0.0.0)
LoadBalancer : Cluster 외부에 제공되는 Load Balancer의 VIP
ExternalName : CNAME 을 사용한 Loosely Coupled
Headless : Pod 의 IP 를 사용한 DNS Round Robin
Kubernetes Ingress
Cluster 외부의 Load Balancer 를 이용한 Ingress : GKE
Cluster 내부의 Ingress 용 Pod 을 이용한 Ingress : Nginx Ingress, Nghttpx Ingress
Kubernetes Config & Storage resource
container 에 대한 설정 파일, 암호 등의 기밀 정보나 Persistent Volume 등에 관한 resource
3 종류
Secret
ConfigMap
PersistentVolumeClaim
환경변수 이용
Kubernetes 에서는 개별 container에 대한 설정의 내용은 환경변수나 파일이 포함된 영역을 mount 해서 넘기는 것이 일반적이다
환경변수를 넘기려면 pod template 에 env 혹은 envFrom 을 지정
5개의 정보 source로부터 환경변수를 심는 것이 가능
정적설정
Pod 정보
Container 정보
Secret resource 의 기밀 정보
ConfigMap resource 의 Key-Value 값
정적설정
spec.containers[].env 에 정적 값을 정의
`apiVersion: v1 kind: Pod metadata: name: sample-env labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 env: - name: MAX_CONNECTION value: "100" `
Pod 정보
Pod 이 속한 Node 나, Pod 의 IP Address, 기동시간 등의 Pod 에 관련된 정보는 fieldRef를 사용하여 참조할 수 있다.
참조 가능한 값은 kubectl get pods -o yaml 등으로 확인할 수 있다.
등록한 YAML file 의 정보와 별도로 IP, host 정도 등도 추가되었다.
`# 동작 중인 Pod 의 정보 확인 $ kubectl get pod nginx-pod -o yaml ... spec: nodeName: gke-k8s-... ... `
`# env-pod-sample.yml # set Kubernetes Node's name to env K8S_NODE apiVersion: v1 kind: Pod metadata: name: sample-env-pod labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 env: - name: K8S_NODE valueFrom: fieldRef: fieldPath: spec.nodeName `
**Container 정보**
Container 에 관련한 정보는 resourceFieldRef를 사용하여 참조할 수 있다.
Pod 에는 복수 container 의 정보가 포함되어 있어서 각 container에 설정 가능한 값에 대해서는 fieldRef로는 참조할 수 없는 것에 주의.
참조 가능한 값에 관해선 kubectl get pods -o yaml 등오로 확인 가능
`# env-container-sample.yml #set CPU Requests/Limits to ENV apiVersion: v1 kind: Pod metadata: name: sample-env-container labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 env: - name: CPU_REQUEST valueFrom: resourceFieldRef: containerName: nginx-container resource: requests.cpu - name: CPU_LIMIT valueFrom: resourceFieldRef: containerName: nginx-container resource: limits.cpu `
**Secret resource 기밀 정보**
기밀 정보는 별도 Secret resource 를 만들어 환경변수로 참조 시키는 것을 추천
ConfigMap resource 에서 Key-Value 값
단순한 Key-Value 값이나 설정 파일 등은 ConfigMap 으로 관리하는 것이 가능
일괄 변경이나 중복이 많이 많은 경우 ConfigMap 을 사용하는 것이 유용할 수 있음
환경변수 이용 시 주의점
`# env fail sample apiVersion: v1 kind: Pod metadata: name: sample-fail-env labels: app: sample-app spec: containers: - name: nginx-container image: nginx:1.12 command: ["echo"] args: ["${TESTENV}", "${HOSTNAME}"] env: - name: TESTENV value: "100" `
command 나 args 에 환경변수를 이용하기 위해선 ${} 가 아닌 $()를 사용해야 한다
command 나 args 에서 참조가능한 환경 변수는 해당 Pod template 내부에서 정의된 환경 변수에 제한된다. (위 예제에서는 TESTENV 값만 참조 가능)
OS 등에서만 참조할 수 있는 환경 변수를 이용하기 위해서는 script 등을 이용하여 실행하도록 해야 한다.
Secret
DataBase 등을 사용할 때 필요한 유저, 암호 등의 인증에 필요한 경우 이용할 수 있는 방식
유저명과 암호를 별도 resource 로 정의해두고 Pod 에서 이를 불러들여 사용하기 위한 resource
Secret이 정의된 YAML Manifest를 암호화하는 ::kubesec:: 이란 OSS 존재
gpg, Google Cloud KMS, AWS KMS 등을 이용하여 간단하게 data.* 부분만 암호화할 수 있어 외부로 공개되어도 문제 소지가 적다.
Docker build 시 Container Image 에 첨부
환경변수나 실행 인수 등에 포함시켜 Container Image 를 build.
기밀 정보를 포함하고 있는 만큼 해당 Image 를 외부에 공개하거나 배포하기 곤란하며 인증 정보가 변경된다면 Image 를 다시 build 해야 하는 등 불편
Pod 이나 Deployment YAML Manifest 에 첨부
이 역시 YAML 이 외부에 알려져서는 안되고 복수 Application 에서 동일한 정보를 사용하게 된다면 여기저기 퍼지게 되는 것이라 이 역시 문제
Secret 분류
Generic (type: Opaque)
TLS (type: kubernetes.io/tls)
Docker Registry (type: kubernetes.io/dockerconfigjson)
Service Account (type: kubernetes.io/service-account-token)
Generic (type: Opaque)
보통 사용하는 암호 등에 이용
작성 방법
file 을 이용 (--from-file)
yaml
kubectl 이용하어 직접 생성 (--from-literal)
envfile
Secret 에서는 복수의 Key-Value 값이 보존된다.
db-auth 라는 이름의 Secret 에는 username, password 라는 Key가 있고 그에 해당하는 Value 값이 존재할 수 있다.
복수의 DB를 사용하는 경우, Secret 이름이 겹치지 않게 정의하거나 시스템별로 Namespace를 분할하는 등의 작업이 필요
from File
--from-file 옵션을 사용하여 파일을 지정하여 사용한다
파일명이 곧 Key 가 되기에 파일명에 포함된 확장자 등은 제거하는게 좋을 수 있다.
확장자를 제거하기 싫다면, --from-file=username=username.txt 처럼 사용할 수도 있다.
파일에 개행문자(\n)가 들어가지 않도록 echo -n 을 사용하는 등으로 주의해야 한다.
`# source 파일 생성 $ echo -n "user" > ./username $ echo -n "password" > ./password # Secret 생성 $ kubectl create secret generic sample-db-auth --from-file=./username --from-file=./password # json 형식으로 base64 형식으로 encode 된 Secret data 부분을 확인 $ kubectl get secret sample-db-auth -o json | jq .data # base64 형식으로 encode 된 내용을 평문으로 확인 $ kubectl get secret sample-db-auth -o json | jq -r .data.username | base64 -d `
from yaml
`apiVersion: v1 kind: Secret metadata: name: sample-db-auth type: Opaque data: username: dXNlcgo= password: cGFzc3dvcmQK `
using kubectl (--from-literal)
—from-literal 옵션 사용
`$ kubectl create secret generic sample-db-auth --from-literal=username=user --from-literal=password=password `
from envfile
일괄적으로 처리할 때 이용가능하며 Docker 에서 —env-file 옵션을 사용하여 container를 사용하고 있었다면 그대로 Secret 에 이식하는 것도 가능하다.
`username=user password=password $ kubectl create secret generic sample-db-auth --from-env-file ./env_secret `
TLS (type: kubernetes.io/tls)
Ingress 등에서 참조 가능한 TLS 용 Secret
주로 인증서 등을 이용하기 위해 사용하며 일반적으로 파일을 이용하여 이용한다.
--key 와 —cert 로 비밀키와 인증서를 지정한다.
`# create certificate $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt - subj "/CN=sample1.example.com" # create TLS Secret $ kubectl create secret tls tls-sample --key /tmp/tls.key --cert /tmp/tls.crt `
Docker Registry (type: kubernetes.io/dockerconfigjson)
Docker Registry 인증 정보용
using kubectl
kubectl 을 이용할 경우 Registry 서버와 인증정보를 인수로 지정한다.
`$ kubectl create secret docker-registry sample-registry-auth \ --docker-server=REGISTRY_SERVER \ --docker-username=REGISTRY_USER \ --docker-password=REGISTRY_USER_PASSWORD \ --docker-email=REGISTRY_USER_EMAIL # get $ kubectl get secret -o json sample-registry-auth | jq .data `
Secret 을 이용한 image 획득
인증이 필요한 Docker Registry 나 Docker Hub 의 Private repository 의 Image 를 가져오기 위해서 Secret 을 사전에 만들어놓고 Pod 의 spec.imagePullSecrets 에 docker-registry 타입의 Secret 을 지정한다.
`# secret-pull_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-pod spec: containers: - name: secret-image-container image: REGISTRY_NAME/secret-image:latest imagePullSecrets: - name: sample-registry-auth `
Service Account
수동으로 만드는 것은 아니지만 Pod 에 Service Account 의 Token 을 mount 하기 위함
Secret 이용
Secret 을 container에서 이용할 경우, 크게 나눠서 2가지 패턴
환경변수
Volume으로 mount
Secret 의 특정 Key 한정
Secret 의 모든 Key
Secret의 특정 Key 한정
Secret 의 모든 키
환경변수
환경변수로 넘길 경우, 특정 Key만을 넘기 던가, Secret 전체를 넘기던가.
특정 key 만을 넘길 경우, spec.containers[].env 의 valueFrom.secretKeyRef 를 사용하여 넘길 키를 지정
`# secret_single_env_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-secret-single-env spec: containers: - name: secret-container image: nginx:1.12 env: - name: DB_USERNAME valueFrom: secretKeyRef: name: sample-db-auth key: username `
env 로 1개씩 정의가 가능하여 환경변수 명을 지정 가능하다.
Secret 전체를 넘길 경우
`# secret_multi_env_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-secret-multi-env spec: containers: - name: secret-container image: nginx:1.12 envFrom: - secretRef: name: sample-db-auth `
Key 를 일일이 지정하지 않아도 되어 간결하지만 Secret 에 저장되어 있는 값을 Pod Template 로는 파악하기 힘들다. **Volume Mount**
특정 Key 만을 넘길 경우, spec.volumes[] 의 secret.item[] 을 사용하여 지정한다.
`# secret_single_volume_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-secret-single-volume spec: containers: - name: secret-container image: nginx:1.12 volumeMounts: - name: config-volume mountPath: /config volumes: - name: config-volume secret: secretName: sample-db-auth items: - key: username path: username.txt `
mount 할 파일을 1개씩 정의할 수 있어 파일명을 지정 가능하다. <pre>`$ kubectl exec -it sample-secret-single-volume cat /config/username.txt `</pre>
Secret 전체를 변수로 넘길 경우
`# secret_multi_volume_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-secret-multi-volume spec: containers: - name: secret-container image: nginx:1.12 volumeMounts: - name: config-volume mountPath: /config volumes: - name: config-volume secret: secretName: sample-db-auth `
`$ kubectl exec -it sample-secret-multi-volume ls /config `
**동적 Secret 갱신** Volume Mount 으로 Secret 을 이용할 경우 일정 기간 주기 (kubelet 의 Sync Loop 의 타이밍) 로 kube-apiserver 에 변경을 확인해서 변경이 있을 경우 갱신한다. 기본적으로 SyncLoop의 간격은 60초로 설정되어 있으나 kuebelet 의 옵션 `—sync-frequency` 로 변경 가능하다. (이는 환경변수를 이요하는 경우에는 이용 불가 하다.) 이 경우 Volume 에 마운트 된 파일의 값이 바뀌어도 Pod 이 재생성 되는 것이 아니어서 끊기는 것을 걱정할 필요도 없다. Secret 에서 삭제된 것 역시 같이 삭제된다. ## ConfigMap ConfigMap 은 설정 정보 등을 Key-Value 로 보존할 수 있는 데이터를 저장하기 위한 resource. Key-Value 라고 해도 nginx.conf 나 httpd.conf 와 같은 설정 파일 그 자체도 보존가능하다. **create ConfigMap** Generic type Secret 과 거의 동일한 방법.
3가지 방법
파일을 사용 (—from-file)
yaml 파일을 사용
kubectl로 직접 생성 (—from-literal)
ConfigMap 에는 복수의 Key-Value 값이 들어간다. nginx.conf 전체를 ConfigMap 안에 넣거나 nginx.conf 의 설정 parameter만 넣어도 된다.
파일을 사용
파일을 사용할 경우. —from-file 을 지정한다. 보통 파일명이 그대로 Key 로 사용되며 Key명을 변경하고 싶을 경우, —from-file=nginx.conf=sample-nginx.conf 와 같은 형식으로 지정한다.
`# create ConfigMap $ kubectl create configmap sample-configmap --from-file=./nginx.conf # 확인 $ kubectl get configmap sample-configmap -o json | jq .data # describe $ kubectl describe configmap sample-configmap `
YAML 파일을 사용
Value 값이 길 경우, Key: | 처럼 정의
`apiVersion: v1 kind: ConfigMap metadata: name: sample-configmap data: thread: "16" connection.max: "100" connection.min: "10" sample.properties: | property.1=value-1 property.2=value-2 property.3=value-3 nginx.conf: | user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; ... `
kubectl 을 사용 (—from-literal)
`$ kubectl create configmap web-config \ --from-literal=connection.max=100 \ --from-literal=connection.min=10 `
ConfigMap 이용
환경변수
Volume mount
특정 Key
모든 Key
특정 Key
모든 Key
환경변수
특정 Key만 넘길 경우, spec.containers[].env 의 valueFrom.configMapKeyRef 를 사용
`# configmap_single_env_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-configmap-single-env spec: containers: - name: configmap-container image: nginx:1.12 env: - name: CONNECTION_MAX valueFrom: configMapKeyRef: name: sample-configmap key: connection.max `
env 한개씩 정의가 가능해서 환경변수명을 지정 가능
모든 Key를 넘길 경우, 한개씩 정의할 필요가 없어 YAML 이 간략해지지만 YAML 만으로는 어떤 값이 있는지 판단하긴 힘들다
`# configmap_multi_env_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-configmap-multi-env spec: containers: - name: configmap-container imgae: nginx:1.12 envFrom: - configMapRef: name: sample-configmap `
환경변수를 이용하는 경우, 다음과 같은 패턴은 표현할 수 없어 전달되지 않는다.
. 이 포함되는 경우
개행이 포함되는 경우. (Key. | 로 정의된 경우)
Volume Mount
특정 Key 만 넘길 경우, spec.volumes[] 의 configMap.items[] 를 사용한다.
`# configmap_single_volume_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-configmap-single-volume spec: containers: - name: configmap-container image: nginx:1.12 volumeMounts: - name: config-volume mountPath: /config volumes: - name: config-volume configMap: name: sample-configmap items: - key: nginx.conf path: nginx-sample.conf `
mount 할 파일을 하나씩 정의하므로 파일명을 지정 가능하다. <pre>`$ kubectl exec -it sample-configmap-single-volume cat /config/nginx-sample.conf `</pre>
모든 Key 를 넘길 경우, YAML 이 간결해지지만 YAML 만으로는 어떤 값이 있는지 판단하기 힘들다.
`# configmap_multi_volume_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-configmap-multi-volume spec: containers: - name: configmap-container image: nginx:1.12 volumeMounts: - name: config-volume mountPath: /config volumes: - name: config-volume configMap: name: sample-configmap `
`$ kubectl exec -it sample-configmap-multi-volume ls /config `
**동적 ConfigMap 갱신** volume mount 를 이용하는 경우, 일정시간 주기 (kubelet 의 Sync Loop 타이밍)로 kube-apiserver 에 변경을 확인해서, 변경이 있으면 갱신한다. SyncLoop 의 기본값은 60초로 설정되어 있으나 이를 변경하고 싶을 경우, kubelet 의 `—sync-frequency` 를 사용하여 설정한다. (환경 변수의 경우 동적 갱신이 불가) ## Volume 과 PersistentVolume, PersistentVolumeClaim 의 차이 Volume 은 기존의 Volume (host 영역, NFS, Ceph, GCP Volume) 등을 YAML Manifest 에 직접 지정하여 이용 가능하게 하는 것이다. 그래서 이용자가 신규로 Volume 을 작성하거나, 기존의 Volume 을 삭제하는 등의 조작이 불가능하다. 그리고 YAML Manifest 로 Volume resource 를 만드는 등의 처리도 불가능하다. PersistentVolume은 외부의 Persistent 한 Volume을 제공하는 시스템과 연계하여 신규 Volume 을 만들거나 기존의 Volume 을 삭제하는 것이 가능하다. 구체적으로는 YAML Manifest 등을 통해 Persistent Volume resource 를 별도 만드는 형식이다. PersistentVolume 의 plug-in 에서는 Volume 의 생성과 삭제와 같은 life cycle 을 처리하는 것이 가능하지만 Volume 의 plug-in 의 경우, 이미 있는 Volume 을 사용하는 것만 가능하다. PersistentVolumeClaim 은 PersistentVolume resource 에서 assign 하기 위한 resource. PersistentVolume은 cluster에 volume 을 등록하기만 하는거라, 실제로 Pod 에서 이용하기 위해서는 PersistentVolumeClaim 을 정의해야 한다. Dynamic Provisioning 기능을 이용할 경우, PersistentVolumeClaim을 이용하는 시점에 Persistent Volume 을 동적으로 생성하는 것이 가능해서 순서가 반대가 될 수 있다. ## Volume [Volume Plug-in](https://kubernetes.io/docs/concepts/storage/volumes/) PersistentVolume과 달리 Pod 에 대해 정적으로 영역을 지정하기 위한 형태가 되기 때문에 충돌(경쟁)에 주의 **EmptyDir**
Pod 의 일시적인 디스크 영역으로 이용 가능
Pod 이 Terminate 되면 삭제됨
`# emptydir-sample.yml apiVersion: v1 kind: Pod metadata: name: sample-emptydir spec: containers: - image: nginx:1.12 name: nginx-container volumeMounts: - mountPath: /cache name: cache-volume volumes: - name: cache-volume emptyDir: {} `
**HostPath**
Kubernetes Node 상의 영역을 container 에 mapping 하기 위한 plug-in.
type
Directory
DirectoryOrCreate
File
Socket
BlockDevice
`# hostpath-sample.yml apiVersion: v1 kind: Pod metadata: name: sample-hostpath spec: containers: - image: nginx:1.12 name: nginx-container volumeMounts: - mountPath: /srv name: hostpath-sample volumes: - name: hostpath-sample hostPath: path: /data type: DirectoryOrCreate `
## PersistentVolume (PV)
Volume 이 Pod 정의에 포함되었다면 PersistentVolume은 resource 로 별도로 작성
엄밀히 말하면 Config&Storage resource 보다 Cluster resource.
PersistentVolume 종류
기본적으로 network 를 이용해 disk attach 한다.
Persistent Volumes - Kubernetes
GCE Persistent Disk
AWS Elastic Block Store
NFS
iSCSI
Ceph
OpenStack Cinder
GlusterFS
create PersistentVolume
label
용량
access mode
reclaim policy
mount option
storage class
setting for each PersistentVolume
`# pv_sample.yml apiVersion: v1 kind: PersistentVolume metadata: name: sample-pv labels: type: nfs envrionment: stg spec: capacity: storage: 10G accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: slow mountOptions: - hard nfs: server: xxx.xxx.xxx.xxx path: /nfs/sample `
`$ kubectl get pv `
**Label** Dynamic Provisioining 을 사용하지 않고 PersistentVolume을 사용하는 경우, 종류가 알 수 없게 되기 쉬우니 type, environment, speed 등의 label 을 붙이는걸 추천한다. Label 을 붙이면 PersistentVolumeClaim 에서 Volume 의 Label 을 지정가능하여 scheduling 을 유난하게 수행할 수 있다. **용량** Dynamic Provisioning 을 이용할 수 없을 경우, 무작정 용량을 크게 잡아선 안 된다. 요구한 용량과 가장 가까운 용량을 가진 storage 가 사용되기 때문. **access mode**
ReadWriteOnce (RWO) : 단일 node 에서 Read / Write
ReadOnlyMany (ROX) : 단일 node 에서 Write, 복수 노드에서 Read
ReadWriteMany (RWX) : 복수 node 에서 Read / Write
Persistent Volumes - Kubernetes
Reclaim Policy
Persistent Volume 사용이 끝난 후 처리방법
Retain
Recycle
Delete
data 를 삭제하지 않고 보존
다른 PersistentVolumeClaim 으로 재 mount 되는 일은 없다
data 삭제 (rm -rf ./*), 재이용가능한 상태로
다른 PersistentVolumeClaim 에서 재 mount 가능
PersistentVolume 삭제
주로 외부 volume 을 사용할 때 사용
Mount Options
PersistentVolume 의 종류에 따라 상이. 확인.
Storage Class
Dynamic Provisioning 의 경우 사용자가 PersistentVolumeClaim 을 사용하여 PersistentVolume 을 요구할 때 원하는 디스크를 지정하기 위해 사용.
Storage Class 선택 = 외부 Volume 종류 선택
`#storageclass_sample.yml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: sample-storageclass parameters: availability: test-zone-la type: scaleio provisioner: kubernetes.io/cinder `
PersistentVolume plug-in 별 설정
실제로는 종류에 따라 제각가이라 확인 필요
PersistentVolumeClaim (PVC)
PersistemtVolumeClaim 에 지정된 조건을 가지고 요구하여 Scheduler 는 현재 보유하고 있는 PersistentVolume 에서 적합한 Volume 을 할당
PersistentVolumeClaim 설정
label selector
capacity
access mode
Storage Class
PVC 에서 요구하는 용량이 PV 용량보다 작으면 할당된다. 8기가를 요구 했는데 딱 맞는게 없고 그 보다 큰 20 기가가 있으면 20기가 를 할당.
NFS 의 경우 Quota 가 걸려 있지 않아 PV 의 용량이 사실상 무시된다.
create PersistentVolumeClaim
`# pvc_sample.yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sample-pvc spec: selector: matchLabels: type: "nfs" matchExpressions: - {key: environment, operator: In, values: [stg]} accessModes: - ReadWriteOnce resources: requests: storage: 4Gi `
`$ kubectl get pvc $ kubectl get pv `
PVC 가 PV 확보에 실패하면 pending 상태가 유지된다.
Retain Policy 를 사용하고 있을 경우, Pod 이 종료되면 Bound 상태에서 Released 상태로 바뀐다. 이 Released 상태가 된 PV 는 PVC 가 재할당하지 않는다.
use in Pod
spec.volumes 의 persistentVolumeClaim.claimName 을 사용
`# pvc_pod_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-pvc-pod spec: containers: - name: nginx-container image: nginx ports: - containerPort: 80 name: "http" volumeMounts: - mountPath: "/usr/share/nginx/html" name: nginx-pvc volumes: - name: nginx-pvc persistentVolumeClaim: className: sample-pvc `
Dynamic Provisioning
동적으로 PV 를 만들기 때문에 용량을 효율적으로 사용하는 것이 가능하고 사전에 PV 를 만들어 둘 필요가 없다.
많은 Provisioner 가 ReadWriteOnce 밖에 지원하지 않는 경우가 많다.
`# Storage Class # storageclass_sample.yml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: sample-storageclass parameters: type: pd-standard provisioner: kubernetes.io/gce-pd reclaimPolicy: Delete `
`# PVC # pvc_provisioner_sample.yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sample-pvc-provisioner annotations: volume.beta.kubernetes.io/storage-class: sample-storageclass spec: accessModes: - ReadWriteOnce resources: requests: storage: 3Gi `
`# Pod # pvc_provisioner_pod_sample.yml apiVersion: v1 kind: Pod metadata: name: sample-pvc-provisioner-pod spec: containers: - name: nginx-container image: nginx prots: - containerPort: 80 name: "http" volumeMounts: - mountPath: "/usr/share/nginx/html" name: nginx-pvc volumes: - name: nginx-pvc persistentVolumeClaim: claimName: sample-pvc-provisioner `
`$ kubectl get pv `
PersistentVolumeClaim in StatefulSet
StatefulSet 에서는 PersistentVolumeClaim 을 이용할 경우가 많고spec.volumeClaimTemplate 을 이용하면 별도로 PVC 를 정의할 필요 없다.
`apiVersion: apps/v1beta1 kind: StatefulSet metadata: ... spec: template: spec: containers: - name: sample-pvct image: nginx:1.12 volumeMounts: - name: pvc-template-volume mountPath: /tmp volumeClaimTemplates: - matadata: name: pvc-template-volume spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: "sample-storageclass"
0 notes
blondiecode-lh · 8 years ago
Text
MongoDB extorted by a kraken ransomware virus. SOLVED
Recently plenty of servers became a victim of hacker attacks. The reason was the vulnerability of non-relational database mongodb. Hackers used this security hole to erase database from the server and demanded a ransom by inserting the following code in your database:
The victim could find this record in mongodb logfile (for ubuntu-servers the path is /var/log/mongodb/mongod.log).
When you recover the database hacker will erase it again, so even if you have backups on your server this will not solve a problem.
What should I do to protect my server?
DO NOT PAY TO THIS RASCAL! He will not return your database.
1. If your database should not be reachable for external ips, you may just disable remote access to a MongoDB server. Change mongod.conf (standart path for Ubuntu is /etc/mongod.conf) and uncomment or add the rule: If you need access to your database from external ip-address go to point 2.
2. Deny all incoming traffic from external ip-adresses on port 27017 (or your custom port for MongoDB server)! For Linux systems use iptables program. Remember that rules in iptables configurations fall into chains and chains have an order. At first you should open the port for some external ip and then close it for others. If you will change an order you will disable access for all ips. Insert this rule to open port for local database Insert rules for external servers that use your database (new rule for each ip) Then deny access for everyone else Attention! Do NOT use this command BEFORE you read next! Important additional information, you can read next rule in mongodb help Change Default Policy to DROP https://docs.mongodb.com/manual/tutorial/configure-linux-iptables-firewall/ iptables -P INPUT DROP Unfortunately some people don't read all sentences. This rule you can use only after completing all iptables configuration, because this rule can close to You all connections to your server including SSH immediately. And you should not use this rule in this exactly case, because closing mongodb port are good enough. But do not worry if you lost connection to your server, just restart it from provider web interface. All iptables rules will be dropped. To check all iptables configuration use this command: To drop ALL iptables: Important! This rules will work up to server restart. So if some rule working wrong and you lost connection to your server, just restart it via your provider web interface. Use iptables-persistent if you need automatically restarting service. Installation: If rules are determined but iptables-peristent are not installed, rules will be saved automatically during installation. To start service: Rules are saved to /etc/iptables/rules.v4 and /etc/iptables/rules.v6
Using this service, you can check your server for open ports: https://www.shodan.io (Just type your server's ip in the search box)
3 notes · View notes
500ok · 6 years ago
Text
OpenStack
Instance Resource Quota
IO limits
OS uses QEMU’s blkdeviotune underneath to apply i/o limits. Limits are setup at flavor level, altering them requires resizing an instance.
Setting up flavor with limits:
nova flavor-key <flavor name> set quota:disk_read_bytes_sec=<limit> nova flavor-key <flavor name> set quota:disk_write_bytes_sec=<limit>
CPU limits
Those are handled with CPU cgroup controller and applied at flavor level as well:
nova flavor-key <flavor name> set quota:cpu_quota=<limit> nova flavor-key <flavor name> set quota:cpu_period=<limit>
Bandwidth limits
Tc is used to control traffic shaping.
nova flavor-key <flavor name> set quota:vif_inbound_average=<limit> nova flavor-key <flavor name> set quota:vif_outbound_average=<limit>
Ref:. https://wiki.openstack.org/wiki/InstanceResourceQuota
Persisting DevStack’s ‘br-ex’ interface configuration across host OS reboots (on Ubuntu 18.04)
Stack.sh
Once stack.sh successfully deploys DevStack the ‘br-ex’ OVS bridge is assigned an IPv4 address of 172.24.4.1/24:
br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether 46:98:c5:26:1d:49 brd ff:ff:ff:ff:ff:ff inet 172.24.4.1/24 brd 172.24.4.255 scope global br-ex   valid_lft forever preferred_lft forever
Also there is an iptables rule for floating IPs masking:
# /sbin/iptables -t nat -L POSTROUTING (...) MASQUERADE  all  --  172.24.4.0/24        anywhere
Once the host OS is rebooted all of the above is lost and OS instances are no longer reachable via floating IPs assigned to them.
Persisting the configuration
Create Netplan yaml file for br-ex interface:
/# cd /etc/netplan/ /etc/netplan# cat 99-br-ex.yaml network:    version: 2    renderer: networkd    ethernets:        br-ex:            addresses:                - 172.24.4.1/24
Test new settings:
/etc/netplan# netplan try (...) Configuration accepted.
Persist iptables rule:
/# cd /etc/networkd-dispatcher/routable.d/ /etc/networkd-dispatcher/routable.d# cat br-ex-snat.sh #!/bin/sh /sbin/iptables -t nat -C POSTROUTING -s 172.24.4.0/24 -d 0.0.0.0/0 -j MASQUERADE 2>/dev/null || /sbin/iptables -t nat -A POSTROUTING -s 172.24.4.0/24 -d 0.0.0.0/0 -j MASQUERADE
0 notes
rodrigocarran · 5 years ago
Text
Como salvar regras do IPTables
Como salvar regras do IPTables
Neste artigo, descreverei várias opções para salvar as regras do IPTables para que sejam carregadas quando o sistema operacional for iniciado.
A melhor opção é instalar o iptables-persistent, por exemplo, no Ubuntu, você pode fazer o seguinte:
1 apt install iptables-persistent
Verifique se o serviço inicia quando o sistema é iniciado:
1 2 systemctl is-enabled…
View On WordPress
0 notes
vidagnublr · 5 years ago
Text
Como salvar las reglas creadas en IPTables en Ubuntu
Como salvar las reglas creadas en #IPTables en #Linux #Ubuntu
La forma mas sencilla de salvar todas las reglas que has configurado en IPTables fue con iptables-persistant, lo primero es instarlos con el siguiente comando.
[simter]$ sudo apt-get install iptables-persistent[/simterm]
Luego para salvar las reglas de iptables utilizas el siguiente comando.
[simter]$ sudo /etc/init.d/iptables-persistent save [/simterm]
Luego para cargar otra vez las…
View On WordPress
0 notes
razpi · 8 years ago
Text
Creating a personal VPN
The Razzer is ideal ideal as a personal VPN server.  No more censored web as you travel, no more insecure connections from your local cafe WiFi.   It’s free and easy.  Why would you not do it?
To begin with, this tutorial assumes you’ve already learned about the security issues around installing a VPN.  If not, go and do this now!  Essentially, you will be opeining up a new port from your local wifi to the internet - a new back door for any hacker to see your network and personal files.  Make sure your firewall is well configured and your passwords for your router, network shares and RaspberryPi administrator accounts are highly sophisticated and un-guess-able.  What you do here is your choice and I cannot be held responsible for someone finding out your bank account details.  Or worse, your secret recipe for gluten free banana loaf bread.
Ok, with that out of the way, it’s all yours.
The first step is to update your RaspberryPi with the latest Linux disto.  Details are in an earlier entry.
The second step is to ensure you can access your Pi from outside your private network from the internet.  The instructions presented here are not a detailed explanation of this - you will need, for example, a fixed address for you RaspberryPi on your network, a port forwarding capability to this address from your router and either a fixed address for your router on the internet, or one of the free online DNS services (try https://www.noip.com/free).
Step 3:
sudo apt-get install openvpn
Step 4:
sudo -s
Step 5:
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/openvpn/easy-rsa
Make sure you have spaces in the right places (before /usr and /etc). This instruction copies all of the files from the easy-rsa 2.0 directory into a directory in your openvpn installation.
Step 6:
cd /etc/openvpn/easy-rsa
Step 7:
nano /etc/openvpn/easy-rsa/vars
Step 8:
In the text that opens find the line that begins: export EASY_RSA=
You need to move the cursor down to edit this line to read:
export EASY_RSA="/etc/openvpn/easy-rsa"
Step 9:
Next move your cursor down until you see the line: export KEY_SIZE=1024
This line can be left as is, but if you are extra paranoid and have time to make a coffee, then change 1024 to 2048.
Step 10:
Keep scrolling to the end of the file and you will see a bunch of export parameters such as Country, Province and City etc. You can choose to change these to set new defaults (this will potentially save you some typing in various later stages), but doing so will not affect the workings of your VPN.
Type CTRL and X then Y then ENTER to save this file.
Step 11:
Build the certificates your VPN will use to grant authority to devices you want to connect with. Open the easy-rsa directory with the command prompt type:
cd /etc/openvpn/easy-rsa
Next type:
source ./vars
./clean-all
./build-ca
This final line builds your certificate authority. The Raspberry Pi will now ask you to complete some additional export values, like Country, Province, City, Organisation etc. (if you changed these in the previous stage you will see your own choices already set as default).
Step 12: Name the server
./build-key-server [ServerName]
… replacing [ServerName] with your choice of name. Call it whatever you like but do not forget it.
You will now be given some more fields to enter values. You can change these or leave them as the defaults, but pay attention to three fields:  
Common Name MUST be the server name you picked.
A challenge password? MUST be left blank.
Sign the certificate? [y/n] Obviously, you must type "y."
Finally when prompted with the question:
1 out of 1 certificate requests certified, commit? [y/n]
Type "y"
Your server is now set up and you need to build keys for all the devices you want to be able to connect.
Step 13:
To assign a user a key type:
./build-key-pass [UserName]
… substituting the [UserName] with your desired text - for example to make a key to connect my android to the VPN I chose the name KateAndroid
You will get some more prompts now:
Enter PEM pass phrase
… choose a password you will remember! It asks you to input this twice to eliminate errors.
A challenge password? MUST be left blank.
Sign the certificate? [y/n]
Hit "y"
Step 14:
Type
cd keys
then (using my example username, which you should change for your own):
openssl rsa -in KateAndroid.key -des3 -out KateAndroid.3des.key
This last line adds an extra layer of encryption to make it harder for hackers to break in.
You will be asked to enter pass phrase for KateAndroid.key - this is the phrase you entered in the previous step.
You will then be asked to enter and repeat a new PEM pass phrase for the des3 key. I used the same pass phrase for both so you only have one to remember. You will need the 3des.key pass phrase at the end of this process when you import your files to your devices.
Repeat these steps for all the usernames you want to build a key for.
You have now created your "client certificates".
Step 15: Generate the Diffie-Hellman key exchange:
This is the code that lets two entities with no prior knowledge of one another share secret keys over a public server. Type:
Type:
cd ..
./build-dh
This is where you go and make a coffee.  And feed the dog.  Then clean out the chicken coop. Have a hair cut.  Book a holiday.  Call that long lost Aunt you’ve been meaning to speak with. Make another coffee.
Step 16: Denial of Service (DoS) attack protection
OpenVPN protects against this kind of attack by generating a static pre-shared hash-based message authentication code (HMAC) key. This means the server will not try to authenticate an access request if it does not detect this key. To generate the static HMAC key type:
openvpn --genkey --secret keys/ta.key
Step 17
nano /etc/openvpn/server.conf
This opens an empty file.  Fill it with this text, taking care to change the details where indicated with a comment in # CAPS LOCK. (Placing a "#" in front of a sentence in the code like this tells the system it is a comment and to ignore it when building the program).  Also when changing the YOUR SERVER NAME sections I refer to the server name that was given to the 'build-key-server' command earlier on.
local 192.168.2.0 # SWAP THIS NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
dev tun
proto udp
port 1194
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/XX.crt # SWAP XX WITH YOUR SERVER NAME
key /etc/openvpn/easy-rsa/keys/XX.key # SWAP XX WITH YOUR SERVER NAME
dh /etc/openvpn/easy-rsa/keys/dh1024.pem # IF YOU CHANGED YOUR ENCRYPTION TO 2048, CHANGE THAT HERE
server 10.8.0.0 255.255.255.0
# server and remote endpoints
ifconfig 10.8.0.1 10.8.0.2
# Add route to Client routing table for the OpenVPN Server
push "route 10.8.0.1 255.255.255.255"
# Add route to Client routing table for the OpenVPN Subnet
push "route 10.8.0.0 255.255.255.0"
# your local subnet
push "route 192.168.0.10 255.255.255.0" # SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
# Set primary domain name server address to the SOHO Router
# If your router does not do DNS, you can use Google DNS 8.8.8.8
push "dhcp-option DNS 192.168.0.1" # THIS SHOULD ALREADY MATCH YOUR OWN ROUTER ADDRESS AND SHOULD NOT NEED TO BE CHANGED
# Override the Client default gateway by using 0.0.0.0/1 and
# 128.0.0.0/1 rather than 0.0.0.0/0. This has the benefit of
# overriding but not wiping out the original default gateway.
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn-status.log 20
log /var/log/openvpn.log
verb 1
Hit CTRL and X then Y and ENTER to save.
Step 17
There is one last edit to make in the server configuration files to make sure your Raspberry Pi knows you want it to forward Internet traffic through our new network.
Type:
nano /etc/sysctl.conf
Near the top it says, "Uncomment the next line to enable packet forwarding for IPv4."
Uncomment this line by removing the hash at the beginning.
Hit CTRL and X, then Y and ENTER to save.
Step 18
Finally you need to action the change you just made in the sysctl.conf file. To do this type:
sysctl -p
You have now made a functioning server that can access the internet.
Step 19 Pass through the firewall
Raspbian has a built-in firewall that will block incoming connections, so we need to tell it to allow traffic from OpenVPN to pass through.
To create a file that will run each time you start up your Raspberry Pi issuing this permission type:
nano /etc/firewall-openvpn-rules.sh
Inside this new file type:
#!/bin/sh
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.0.10
# SWAP THE IP NUMBER WITH YOUR RASPBERRY PI IP ADDRESS
CTRL and X then Y and ENTER to save.
Newly created files are not executable by default, so we will need to change the permissions and ownership of this file you just created. To do this type:
chmod 700 /etc/firewall-openvpn-rules.sh
then:
chown root /etc/firewall-openvpn-rules.sh
This script gives OpenVPN permission to breach the firewall.
Step 20
Now need to add it into the interfaces setup code so it runs on boot. Type:
nano /etc/network/interfaces
Find the line that says: "iface eth0 inet static." We want to add a line below the list of numbers that follow it. This line needs to be added at an indent so hit TAB first:
pre-up /etc/firewall-openvpn-rules.sh
CTRL and X then Y and ENTER to save.
Finally, reboot your Raspberry Pi by typing:
Reboot
Step 21: Create profile scripts for the devices you want to connect
We have created keys for clients (computers and devices) to use to connect to your VPN, but we have not told the clients where to find the server, how to connect, or which key to use.
If you created several different client keys for each of the devices you want to grant access, it would be a lot of trouble to generate a new configuration file for each client from scratch.
Luckily Eric Jodoin of the SANS institute has written a script to generate them automatically.
First type:
sudo nano /etc/openvpn/easy-rsa/keys/Default.txt
Fill in the blank text file with the following:
client
dev tun
proto udp
remote [YOUR PUBLIC IP ADDRESS] 1194  #REPLACE YOUR DYNAMIC DNS VALUE FROM CHANGEIP.COM
resolv-retry infinite
nobind
persist-key
persist-tun
mute-replay-warnings
ns-cert-type server
key-direction 1
cipher AES-128-CBC
comp-lzo
verb 1
mute 20
CTRL and X then Y and ENTER to save.
Step 22: Create the script that makes your profile keys
type:
sudo nano /etc/openvpn/easy-rsa/keys/MakeOVPN.sh
In this file you need to add the text that Jodoin wrote to create the script:
#!/bin/bash
# Default Variable Declarations
DEFAULT="Default.txt"
FILEEXT=".ovpn"
CRT=".crt"
KEY=".3des.key"
CA="ca.crt"
TA="ta.key"
#Ask for a Client name
echo "Please enter an existing Client Name:"
read NAME
#1st Verify that client's Public Key Exists
if [ ! -f $NAME$CRT ]; then
echo "[ERROR]: Client Public Key Certificate not found: $NAME$CRT"
exit
fi
echo "Client's cert found: $NAME$CR"
#Then, verify that there is a private key for that client
if [ ! -f $NAME$KEY ]; then
echo "[ERROR]: Client 3des Private Key not found: $NAME$KEY"
exit
fi
echo "Client's Private Key found: $NAME$KEY"
#Confirm the CA public key exists
if [ ! -f $CA ]; then
echo "[ERROR]: CA Public Key not found: $CA"
exit
fi
echo "CA public Key found: $CA"
#Confirm the tls-auth ta key file exists
if [ ! -f $TA ]; then
echo "[ERROR]: tls-auth Key not found: $TA"
exit
fi
echo "tls-auth Private Key found: $TA"
#Ready to make a new .opvn file - Start by populating with the default file
cat $DEFAULT > $NAME$FILEEXT
#Now, append the CA Public Cert
echo "<ca>" >> $NAME$FILEEXT
cat $CA >> $NAME$FILEEXT
echo "</ca>" >> $NAME$FILEEXT
#Next append the client Public Cert
echo "<cert>" >> $NAME$FILEEXT
cat $NAME$CRT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' >> $NAME$FILEEXT
echo "</cert>" >> $NAME$FILEEXT
#Then, append the client Private Key
echo "<key>" >> $NAME$FILEEXT
cat $NAME$KEY >> $NAME$FILEEXT
echo "</key>" >> $NAME$FILEEXT
#Finally, append the TA Private Key
echo "<tls-auth>" >> $NAME$FILEEXT
cat $TA >> $NAME$FILEEXT
echo "</tls-auth>" >> $NAME$FILEEXT
echo "Done! $NAME$FILEEXT Successfully Created."
#Script written by Eric Jodoin
\ No newline at end of file
CTRL and X then Y and ENTER to save.
Step 23
Next you need to give this script permission to run. Type:
cd /etc/openvpn/easy-rsa/keys/
NB: If you have issues with CD, try sudo chmod go+rx /etc/openvpn/easy-rsa/keys/ first.
The to give it root privileges type:
chmod 700 MakeOVPN.sh
Finally, execute the script with:
./MakeOVPN.sh
As it runs, it will ask you to input the usernames names of the clients for you generated keys for earlier (in my case KateAndroid). Type that when prompted and you should see the line:
Done! KateAndroid.ovpn Successfully Created.
Repeat this step for each additional username you added client.
Client Software Recommendations:
http://www.wikihow.com/Connect-to-an-OpenVPN-Server
Mac
https://tunnelblick.net/downloads.html
http://accc.uic.edu/answer/how-do-i-configure-and-use-openvpn-macos
Windows PC
Windows Mobile
iOS
0 notes