mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-16 14:52:43 -08:00
Translated ['.github/pull_request_template.md', 'src/pentesting-cloud/az
This commit is contained in:
@@ -4,91 +4,90 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**The original author of this page is** [**Jorge**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **(read his original post** [**here**](https://sickrov.github.io)**)**
|
||||
**このページの元の著者は** [**ホルヘ**](https://www.linkedin.com/in/jorge-belmonte-a924b616b/) **です(彼の元の投稿は** [**こちら**](https://sickrov.github.io)**)**
|
||||
|
||||
## Architecture & Basics
|
||||
## アーキテクチャと基本
|
||||
|
||||
### What does Kubernetes do?
|
||||
### Kubernetesは何をするのか?
|
||||
|
||||
- Allows running container/s in a container engine.
|
||||
- Schedule allows containers mission efficient.
|
||||
- Keep containers alive.
|
||||
- Allows container communications.
|
||||
- Allows deployment techniques.
|
||||
- Handle volumes of information.
|
||||
- コンテナエンジンでコンテナを実行できる。
|
||||
- スケジュールによりコンテナのミッションを効率的に行う。
|
||||
- コンテナを生かしておく。
|
||||
- コンテナ間の通信を可能にする。
|
||||
- デプロイメント技術を許可する。
|
||||
- 情報のボリュームを処理する。
|
||||
|
||||
### Architecture
|
||||
### アーキテクチャ
|
||||
|
||||

|
||||
|
||||
- **Node**: operating system with pod or pods.
|
||||
- **Pod**: Wrapper around a container or multiple containers with. A pod should only contain one application (so usually, a pod run just 1 container). The pod is the way kubernetes abstracts the container technology running.
|
||||
- **Service**: Each pod has 1 internal **IP address** from the internal range of the node. However, it can be also exposed via a service. The **service has also an IP address** and its goal is to maintain the communication between pods so if one dies the **new replacement** (with a different internal IP) **will be accessible** exposed in the **same IP of the service**. It can be configured as internal or external. The service also actuates as a **load balancer when 2 pods are connected** to the same service.\
|
||||
When a **service** is **created** you can find the endpoints of each service running `kubectl get endpoints`
|
||||
- **Kubelet**: Primary node agent. The component that establishes communication between node and kubectl, and only can run pods (through API server). The kubelet doesn’t manage containers that were not created by Kubernetes.
|
||||
- **Kube-proxy**: is the service in charge of the communications (services) between the apiserver and the node. The base is an IPtables for nodes. Most experienced users could install other kube-proxies from other vendors.
|
||||
- **Sidecar container**: Sidecar containers are the containers that should run along with the main container in the pod. This sidecar pattern extends and enhances the functionality of current containers without changing them. Nowadays, We know that we use container technology to wrap all the dependencies for the application to run anywhere. A container does only one thing and does that thing very well.
|
||||
- **Master process:**
|
||||
- **Api Server:** Is the way the users and the pods use to communicate with the master process. Only authenticated request should be allowed.
|
||||
- **Scheduler**: Scheduling refers to making sure that Pods are matched to Nodes so that Kubelet can run them. It has enough intelligence to decide which node has more available resources the assign the new pod to it. Note that the scheduler doesn't start new pods, it just communicate with the Kubelet process running inside the node, which will launch the new pod.
|
||||
- **Kube Controller manager**: It checks resources like replica sets or deployments to check if, for example, the correct number of pods or nodes are running. In case a pod is missing, it will communicate with the scheduler to start a new one. It controls replication, tokens, and account services to the API.
|
||||
- **etcd**: Data storage, persistent, consistent, and distributed. Is Kubernetes’s database and the key-value storage where it keeps the complete state of the clusters (each change is logged here). Components like the Scheduler or the Controller manager depends on this date to know which changes have occurred (available resourced of the nodes, number of pods running...)
|
||||
- **Cloud controller manager**: Is the specific controller for flow controls and applications, i.e: if you have clusters in AWS or OpenStack.
|
||||
- **ノード**: ポッドまたはポッドを持つオペレーティングシステム。
|
||||
- **ポッド**: コンテナまたは複数のコンテナを包むラッパー。ポッドは通常、1つのアプリケーションのみを含むべきである(通常、ポッドは1つのコンテナを実行する)。ポッドはKubernetesが実行しているコンテナ技術を抽象化する方法である。
|
||||
- **サービス**: 各ポッドはノードの内部範囲から1つの内部**IPアドレス**を持つ。しかし、サービスを介して公開することもできる。**サービスにもIPアドレスがあり**、その目的はポッド間の通信を維持することである。したがって、1つのポッドが死んだ場合、**新しい置き換え**(異なる内部IPを持つ)**がサービスの同じIPでアクセス可能になる**。内部または外部として構成できる。サービスはまた、**2つのポッドが同じサービスに接続されているときにロードバランサーとして機能する**。\
|
||||
サービスが**作成されると**、`kubectl get endpoints`を実行して各サービスのエンドポイントを見つけることができる。
|
||||
- **Kubelet**: プライマリノードエージェント。ノードとkubectl間の通信を確立するコンポーネントであり、ポッドのみを実行できる(APIサーバーを介して)。KubeletはKubernetesによって作成されていないコンテナを管理しない。
|
||||
- **Kube-proxy**: apiserverとノード間の通信(サービス)を担当するサービスである。ノードのためのIPtablesが基本である。経験豊富なユーザーは、他のベンダーからの他のkube-proxiesをインストールすることができる。
|
||||
- **サイドカーコンテナ**: サイドカーコンテナは、ポッド内のメインコンテナと一緒に実行されるべきコンテナである。このサイドカーパターンは、現在のコンテナの機能を変更することなく拡張し強化する。現在、私たちはアプリケーションがどこでも実行できるようにすべての依存関係をラップするためにコンテナ技術を使用していることを知っている。コンテナは1つのことだけを行い、そのことを非常にうまく行う。
|
||||
- **マスタープロセス:**
|
||||
- **Api Server:** ユーザーとポッドがマスタープロセスと通信するための方法である。認証されたリクエストのみが許可されるべきである。
|
||||
- **スケジューラ**: スケジューリングは、ポッドがノードにマッチすることを確認することを指す。Kubeletがそれらを実行できるようにする。どのノードがより多くのリソースを利用可能かを決定するための十分な知性を持っており、新しいポッドをそれに割り当てる。スケジューラは新しいポッドを開始するのではなく、ノード内で実行されているKubeletプロセスと通信し、新しいポッドを起動する。
|
||||
- **Kube Controller manager**: レプリカセットやデプロイメントなどのリソースをチェックし、例えば、正しい数のポッドやノードが実行されているかを確認する。ポッドが欠けている場合、新しいポッドを開始するためにスケジューラと通信する。APIへのレプリケーション、トークン、およびアカウントサービスを制御する。
|
||||
- **etcd**: データストレージ、永続的、一貫性があり、分散型。Kubernetesのデータベースであり、クラスターの完全な状態を保持するキー-バリューストレージ(各変更はここに記録される)。スケジューラやコントローラーマネージャーなどのコンポーネントは、どの変更が発生したかを知るためにこのデータに依存する(ノードの利用可能なリソース、実行中のポッドの数...)。
|
||||
- **Cloud controller manager**: フロー制御とアプリケーションのための特定のコントローラーである。つまり、AWSやOpenStackにクラスターがある場合。
|
||||
|
||||
Note that as the might be several nodes (running several pods), there might also be several master processes which their access to the Api server load balanced and their etcd synchronized.
|
||||
ノードが複数(複数のポッドを実行)される可能性があるため、Apiサーバーへのアクセスが負荷分散され、etcdが同期される複数のマスタープロセスが存在する可能性があることに注意してください。
|
||||
|
||||
**Volumes:**
|
||||
**ボリューム:**
|
||||
|
||||
When a pod creates data that shouldn't be lost when the pod disappear it should be stored in a physical volume. **Kubernetes allow to attach a volume to a pod to persist the data**. The volume can be in the local machine or in a **remote storage**. If you are running pods in different physical nodes you should use a remote storage so all the pods can access it.
|
||||
ポッドがデータを作成し、それがポッドが消えるときに失われるべきでない場合、それは物理ボリュームに保存されるべきである。**Kubernetesはデータを永続化するためにポッドにボリュームをアタッチすることを許可する**。ボリュームはローカルマシンまたは**リモートストレージ**に存在する可能性がある。異なる物理ノードでポッドを実行している場合、すべてのポッドがアクセスできるようにリモートストレージを使用するべきである。
|
||||
|
||||
**Other configurations:**
|
||||
**その他の構成:**
|
||||
|
||||
- **ConfigMap**: You can configure **URLs** to access services. The pod will obtain data from here to know how to communicate with the rest of the services (pods). Note that this is not the recommended place to save credentials!
|
||||
- **Secret**: This is the place to **store secret data** like passwords, API keys... encoded in B64. The pod will be able to access this data to use the required credentials.
|
||||
- **Deployments**: This is where the components to be run by kubernetes are indicated. A user usually won't work directly with pods, pods are abstracted in **ReplicaSets** (number of same pods replicated), which are run via deployments. Note that deployments are for **stateless** applications. The minimum configuration for a deployment is the name and the image to run.
|
||||
- **StatefulSet**: This component is meant specifically for applications like **databases** which needs to **access the same storage**.
|
||||
- **Ingress**: This is the configuration that is use to **expose the application publicly with an URL**. Note that this can also be done using external services, but this is the correct way to expose the application.
|
||||
- If you implement an Ingress you will need to create **Ingress Controllers**. The Ingress Controller is a **pod** that will be the endpoint that will receive the requests and check and will load balance them to the services. the ingress controller will **send the request based on the ingress rules configured**. Note that the ingress rules can point to different paths or even subdomains to different internal kubernetes services.
|
||||
- A better security practice would be to use a cloud load balancer or a proxy server as entrypoint to don't have any part of the Kubernetes cluster exposed.
|
||||
- When request that doesn't match any ingress rule is received, the ingress controller will direct it to the "**Default backend**". You can `describe` the ingress controller to get the address of this parameter.
|
||||
- `minikube addons enable ingress`
|
||||
- **ConfigMap**: サービスにアクセスするための**URL**を構成できる。ポッドはここからデータを取得して、他のサービス(ポッド)と通信する方法を知る。これは資格情報を保存するための推奨場所ではないことに注意してください!
|
||||
- **Secret**: これは**パスワード、APIキー...**などの秘密データをB64でエンコードして**保存する場所**である。ポッドは必要な資格情報を使用するためにこのデータにアクセスできる。
|
||||
- **Deployments**: これはKubernetesによって実行されるコンポーネントが示される場所である。ユーザーは通常ポッドと直接作業しない。ポッドは**ReplicaSets**(複製された同じポッドの数)で抽象化され、デプロイメントを介して実行される。デプロイメントは**ステートレス**アプリケーションのためのものであることに注意してください。デプロイメントの最小構成は、名前と実行するイメージである。
|
||||
- **StatefulSet**: このコンポーネントは、**データベース**のようなアプリケーション専用であり、**同じストレージにアクセスする必要がある**。
|
||||
- **Ingress**: これは**アプリケーションをURLで公開するために使用される構成**である。これは外部サービスを使用しても行うことができるが、アプリケーションを公開するための正しい方法であることに注意してください。
|
||||
- Ingressを実装する場合、**Ingress Controllers**を作成する必要がある。Ingressコントローラーは、リクエストを受け取り、チェックし、サービスに負荷分散するエンドポイントとなる**ポッド**である。Ingressコントローラーは**構成されたIngressルールに基づいてリクエストを送信する**。Ingressルールは、異なるパスや異なる内部Kubernetesサービスへのサブドメインを指すことができることに注意してください。
|
||||
- より良いセキュリティプラクティスは、Kubernetesクラスターのどの部分も公開しないように、エントリーポイントとしてクラウドロードバランサーまたはプロキシサーバーを使用することである。
|
||||
- どのIngressルールにも一致しないリクエストが受信されると、Ingressコントローラーはそれを「**デフォルトバックエンド**」に向ける。`describe`コマンドを使用してIngressコントローラーのこのパラメータのアドレスを取得できる。
|
||||
- `minikube addons enable ingress`
|
||||
|
||||
### PKI infrastructure - Certificate Authority CA:
|
||||
### PKIインフラストラクチャ - 証明書機関CA:
|
||||
|
||||

|
||||
|
||||
- CA is the trusted root for all certificates inside the cluster.
|
||||
- Allows components to validate to each other.
|
||||
- All cluster certificates are signed by the CA.
|
||||
- ETCd has its own certificate.
|
||||
- types:
|
||||
- apiserver cert.
|
||||
- kubelet cert.
|
||||
- scheduler cert.
|
||||
- CAはクラスター内のすべての証明書の信頼されたルートである。
|
||||
- コンポーネントが互いに検証できるようにする。
|
||||
- すべてのクラスター証明書はCAによって署名される。
|
||||
- etcdは独自の証明書を持つ。
|
||||
- タイプ:
|
||||
- apiserver証明書。
|
||||
- kubelet証明書。
|
||||
- スケジューラ証明書。
|
||||
|
||||
## Basic Actions
|
||||
## 基本的なアクション
|
||||
|
||||
### Minikube
|
||||
|
||||
**Minikube** can be used to perform some **quick tests** on kubernetes without needing to deploy a whole kubernetes environment. It will run the **master and node processes in one machine**. Minikube will use virtualbox to run the node. See [**here how to install it**](https://minikube.sigs.k8s.io/docs/start/).
|
||||
|
||||
**Minikube**は、完全なKubernetes環境をデプロイすることなく、Kubernetes上でいくつかの**クイックテスト**を実行するために使用できる。**マスターとノードプロセスを1台のマシンで実行する**。Minikubeはノードを実行するためにVirtualBoxを使用する。 [**こちらでインストール方法を確認してください**](https://minikube.sigs.k8s.io/docs/start/)。
|
||||
```
|
||||
$ minikube start
|
||||
😄 minikube v1.19.0 on Ubuntu 20.04
|
||||
✨ Automatically selected the virtualbox driver. Other choices: none, ssh
|
||||
💿 Downloading VM boot image ...
|
||||
> minikube-v1.19.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
|
||||
> minikube-v1.19.0.iso: 244.49 MiB / 244.49 MiB 100.00% 1.78 MiB p/s 2m17.
|
||||
> minikube-v1.19.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
|
||||
> minikube-v1.19.0.iso: 244.49 MiB / 244.49 MiB 100.00% 1.78 MiB p/s 2m17.
|
||||
👍 Starting control plane node minikube in cluster minikube
|
||||
💾 Downloading Kubernetes v1.20.2 preload ...
|
||||
> preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB 100.00% 2.59 MiB
|
||||
> preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB 100.00% 2.59 MiB
|
||||
🔥 Creating virtualbox VM (CPUs=2, Memory=3900MB, Disk=20000MB) ...
|
||||
🐳 Preparing Kubernetes v1.20.2 on Docker 20.10.4 ...
|
||||
▪ Generating certificates and keys ...
|
||||
▪ Booting up control plane ...
|
||||
▪ Configuring RBAC rules ...
|
||||
▪ Generating certificates and keys ...
|
||||
▪ Booting up control plane ...
|
||||
▪ Configuring RBAC rules ...
|
||||
🔎 Verifying Kubernetes components...
|
||||
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
|
||||
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
|
||||
🌟 Enabled addons: storage-provisioner, default-storageclass
|
||||
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by defaul
|
||||
|
||||
@@ -106,11 +105,9 @@ $ minikube delete
|
||||
🔥 Deleting "minikube" in virtualbox ...
|
||||
💀 Removed all traces of the "minikube" cluster
|
||||
```
|
||||
### Kubectlの基本
|
||||
|
||||
### Kubectl Basics
|
||||
|
||||
**`Kubectl`** is the command line tool for kubernetes clusters. It communicates with the Api server of the master process to perform actions in kubernetes or to ask for data.
|
||||
|
||||
**`Kubectl`** は、kubernetesクラスター用のコマンドラインツールです。これは、kubernetes内でアクションを実行したりデータを要求したりするために、マスタープロセスのApiサーバーと通信します。
|
||||
```bash
|
||||
kubectl version #Get client and server version
|
||||
kubectl get pod
|
||||
@@ -141,188 +138,172 @@ kubectl delete deployment mongo-depl
|
||||
#Deploy from config file
|
||||
kubectl apply -f deployment.yml
|
||||
```
|
||||
### Minikube ダッシュボード
|
||||
|
||||
### Minikube Dashboard
|
||||
|
||||
The dashboard allows you to see easier what is minikube running, you can find the URL to access it in:
|
||||
|
||||
ダッシュボードを使用すると、minikube が何を実行しているかをより簡単に確認できます。アクセスするための URL は次の場所にあります:
|
||||
```
|
||||
minikube dashboard --url
|
||||
|
||||
|
||||
🔌 Enabling dashboard ...
|
||||
▪ Using image kubernetesui/dashboard:v2.3.1
|
||||
▪ Using image kubernetesui/metrics-scraper:v1.0.7
|
||||
▪ Using image kubernetesui/dashboard:v2.3.1
|
||||
▪ Using image kubernetesui/metrics-scraper:v1.0.7
|
||||
🤔 Verifying dashboard health ...
|
||||
🚀 Launching proxy ...
|
||||
🤔 Verifying proxy health ...
|
||||
http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/
|
||||
```
|
||||
### YAML構成ファイルの例
|
||||
|
||||
### YAML configuration files examples
|
||||
各構成ファイルには3つの部分があります: **metadata**、**specification**(起動する必要があるもの)、**status**(望ましい状態)。\
|
||||
デプロイメント構成ファイルの仕様の中には、実行するイメージを定義する新しい構成構造で定義されたテンプレートがあります:
|
||||
|
||||
Each configuration file has 3 parts: **metadata**, **specification** (what need to be launch), **status** (desired state).\
|
||||
Inside the specification of the deployment configuration file you can find the template defined with a new configuration structure defining the image to run:
|
||||
|
||||
**Example of Deployment + Service declared in the same configuration file (from** [**here**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**
|
||||
|
||||
As a service usually is related to one deployment it's possible to declare both in the same configuration file (the service declared in this config is only accessible internally):
|
||||
**同じ構成ファイルで宣言されたDeployment + Serviceの例(** [**こちら**](https://gitlab.com/nanuchi/youtube-tutorial-series/-/blob/master/demo-kubernetes-components/mongo.yaml)**)**
|
||||
|
||||
サービスは通常1つのデプロイメントに関連付けられているため、同じ構成ファイルで両方を宣言することが可能です(この構成で宣言されたサービスは内部からのみアクセス可能です):
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mongodb-deployment
|
||||
labels:
|
||||
app: mongodb
|
||||
name: mongodb-deployment
|
||||
labels:
|
||||
app: mongodb
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongodb
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mongodb
|
||||
spec:
|
||||
containers:
|
||||
- name: mongodb
|
||||
image: mongo
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
env:
|
||||
- name: MONGO_INITDB_ROOT_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb-secret
|
||||
key: mongo-root-username
|
||||
- name: MONGO_INITDB_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb-secret
|
||||
key: mongo-root-password
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mongodb
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mongodb
|
||||
spec:
|
||||
containers:
|
||||
- name: mongodb
|
||||
image: mongo
|
||||
ports:
|
||||
- containerPort: 27017
|
||||
env:
|
||||
- name: MONGO_INITDB_ROOT_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb-secret
|
||||
key: mongo-root-username
|
||||
- name: MONGO_INITDB_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mongodb-secret
|
||||
key: mongo-root-password
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongodb-service
|
||||
name: mongodb-service
|
||||
spec:
|
||||
selector:
|
||||
app: mongodb
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
selector:
|
||||
app: mongodb
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 27017
|
||||
targetPort: 27017
|
||||
```
|
||||
**外部サービス構成の例**
|
||||
|
||||
**Example of external service config**
|
||||
|
||||
This service will be accessible externally (check the `nodePort` and `type: LoadBlancer` attributes):
|
||||
|
||||
このサービスは外部からアクセス可能です(`nodePort` と `type: LoadBlancer` 属性を確認してください):
|
||||
```yaml
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mongo-express-service
|
||||
name: mongo-express-service
|
||||
spec:
|
||||
selector:
|
||||
app: mongo-express
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
nodePort: 30000
|
||||
selector:
|
||||
app: mongo-express
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
nodePort: 30000
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> This is useful for testing but for production you should have only internal services and an Ingress to expose the application.
|
||||
> これはテストに役立ちますが、本番環境では内部サービスのみを持ち、アプリケーションを公開するためにIngressを使用するべきです。
|
||||
|
||||
**Example of Ingress config file**
|
||||
|
||||
This will expose the application in `http://dashboard.com`.
|
||||
**Ingress構成ファイルの例**
|
||||
|
||||
これにより、アプリケーションが`http://dashboard.com`で公開されます。
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: dashboard-ingress
|
||||
namespace: kubernetes-dashboard
|
||||
name: dashboard-ingress
|
||||
namespace: kubernetes-dashboard
|
||||
spec:
|
||||
rules:
|
||||
- host: dashboard.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: kubernetes-dashboard
|
||||
servicePort: 80
|
||||
rules:
|
||||
- host: dashboard.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: kubernetes-dashboard
|
||||
servicePort: 80
|
||||
```
|
||||
**シークレット設定ファイルの例**
|
||||
|
||||
**Example of secrets config file**
|
||||
|
||||
Note how the password are encoded in B64 (which isn't secure!)
|
||||
|
||||
パスワードがB64でエンコードされていることに注意してください(これは安全ではありません!)
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mongodb-secret
|
||||
name: mongodb-secret
|
||||
type: Opaque
|
||||
data:
|
||||
mongo-root-username: dXNlcm5hbWU=
|
||||
mongo-root-password: cGFzc3dvcmQ=
|
||||
mongo-root-username: dXNlcm5hbWU=
|
||||
mongo-root-password: cGFzc3dvcmQ=
|
||||
```
|
||||
**ConfigMapの例**
|
||||
|
||||
**Example of ConfigMap**
|
||||
|
||||
A **ConfigMap** is the configuration that is given to the pods so they know how to locate and access other services. In this case, each pod will know that the name `mongodb-service` is the address of a pod that they can communicate with (this pod will be executing a mongodb):
|
||||
|
||||
**ConfigMap**は、ポッドに提供される設定であり、ポッドが他のサービスをどのように見つけてアクセスするかを知るためのものです。この場合、各ポッドは、`mongodb-service`という名前が、通信できるポッドのアドレスであることを知ります(このポッドはmongodbを実行します):
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mongodb-configmap
|
||||
name: mongodb-configmap
|
||||
data:
|
||||
database_url: mongodb-service
|
||||
database_url: mongodb-service
|
||||
```
|
||||
|
||||
Then, inside a **deployment config** this address can be specified in the following way so it's loaded inside the env of the pod:
|
||||
|
||||
次に、**deployment config**内で、このアドレスは次のように指定でき、ポッドのenv内にロードされます:
|
||||
```yaml
|
||||
[...]
|
||||
spec:
|
||||
[...]
|
||||
template:
|
||||
[...]
|
||||
spec:
|
||||
containers:
|
||||
- name: mongo-express
|
||||
image: mongo-express
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
env:
|
||||
- name: ME_CONFIG_MONGODB_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: mongodb-configmap
|
||||
key: database_url
|
||||
[...]
|
||||
template:
|
||||
[...]
|
||||
spec:
|
||||
containers:
|
||||
- name: mongo-express
|
||||
image: mongo-express
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
env:
|
||||
- name: ME_CONFIG_MONGODB_SERVER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: mongodb-configmap
|
||||
key: database_url
|
||||
[...]
|
||||
```
|
||||
**ボリューム設定の例**
|
||||
|
||||
**Example of volume config**
|
||||
さまざまなストレージ構成のyamlファイルの例は、[https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes)で見つけることができます。\
|
||||
**ボリュームは名前空間の中にはありません**
|
||||
|
||||
You can find different example of storage configuration yaml files in [https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes](https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes).\
|
||||
**Note that volumes aren't inside namespaces**
|
||||
### 名前空間
|
||||
|
||||
### Namespaces
|
||||
Kubernetesは、同じ物理クラスターにバックアップされた**複数の仮想クラスター**をサポートしています。これらの仮想クラスターは**名前空間**と呼ばれています。これは、複数のチームやプロジェクトにまたがる多くのユーザーがいる環境での使用を目的としています。数人から十数人のユーザーがいるクラスターでは、名前空間を作成したり考えたりする必要はありません。Kubernetesにデプロイされたアプリケーションの各部分をより良く制御し、整理するために名前空間を使用し始めるべきです。
|
||||
|
||||
Kubernetes supports **multiple virtual clusters** backed by the same physical cluster. These virtual clusters are called **namespaces**. These are intended for use in environments with many users spread across multiple teams, or projects. For clusters with a few to tens of users, you should not need to create or think about namespaces at all. You only should start using namespaces to have a better control and organization of each part of the application deployed in kubernetes.
|
||||
|
||||
Namespaces provide a scope for names. Names of resources need to be unique within a namespace, but not across namespaces. Namespaces cannot be nested inside one another and **each** Kubernetes **resource** can only be **in** **one** **namespace**.
|
||||
|
||||
There are 4 namespaces by default if you are using minikube:
|
||||
名前空間は名前のスコープを提供します。リソースの名前は名前空間内で一意である必要がありますが、名前空間間では一意である必要はありません。名前空間は互いにネストすることはできず、**各**Kubernetes **リソース**は**1つの** **名前空間**の中にのみ存在できます。
|
||||
|
||||
minikubeを使用している場合、デフォルトで4つの名前空間があります:
|
||||
```
|
||||
kubectl get namespace
|
||||
NAME STATUS AGE
|
||||
@@ -331,116 +312,108 @@ kube-node-lease Active 1d
|
||||
kube-public Active 1d
|
||||
kube-system Active 1d
|
||||
```
|
||||
|
||||
- **kube-system**: It's not meant or the users use and you shouldn't touch it. It's for master and kubectl processes.
|
||||
- **kube-public**: Publicly accessible date. Contains a configmap which contains cluster information
|
||||
- **kube-node-lease**: Determines the availability of a node
|
||||
- **default**: The namespace the user will use to create resources
|
||||
|
||||
- **kube-system**: ユーザーが使用するためのものではなく、触れるべきではありません。マスターとkubectlプロセスのためのものです。
|
||||
- **kube-public**: 公開アクセス可能なデータ。クラスター情報を含むconfigmapが含まれています。
|
||||
- **kube-node-lease**: ノードの可用性を決定します。
|
||||
- **default**: ユーザーがリソースを作成するために使用する名前空間です。
|
||||
```bash
|
||||
#Create namespace
|
||||
kubectl create namespace my-namespace
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Note that most Kubernetes resources (e.g. pods, services, replication controllers, and others) are in some namespaces. However, other resources like namespace resources and low-level resources, such as nodes and persistenVolumes are not in a namespace. To see which Kubernetes resources are and aren’t in a namespace:
|
||||
> 注意すべきは、ほとんどのKubernetesリソース(例:ポッド、サービス、レプリケーションコントローラーなど)は、いくつかのネームスペースに存在します。しかし、ネームスペースリソースやノード、persistentVolumesなどの低レベルリソースはネームスペースに存在しません。どのKubernetesリソースがネームスペースにあり、どれがないかを確認するには:
|
||||
>
|
||||
> ```bash
|
||||
> kubectl api-resources --namespaced=true #In a namespace
|
||||
> kubectl api-resources --namespaced=false #Not in a namespace
|
||||
> kubectl api-resources --namespaced=true #ネームスペース内
|
||||
> kubectl api-resources --namespaced=false #ネームスペース外
|
||||
> ```
|
||||
|
||||
You can save the namespace for all subsequent kubectl commands in that context.
|
||||
|
||||
そのコンテキスト内で、すべての後続のkubectlコマンドのためにネームスペースを保存できます。
|
||||
```bash
|
||||
kubectl config set-context --current --namespace=<insert-namespace-name-here>
|
||||
```
|
||||
|
||||
### Helm
|
||||
|
||||
Helm is the **package manager** for Kubernetes. It allows to package YAML files and distribute them in public and private repositories. These packages are called **Helm Charts**.
|
||||
|
||||
HelmはKubernetesの**パッケージマネージャー**です。YAMLファイルをパッケージ化し、公開およびプライベートリポジトリで配布することができます。これらのパッケージは**Helm Charts**と呼ばれます。
|
||||
```
|
||||
helm search <keyword>
|
||||
```
|
||||
Helmは、変数を使用して設定ファイルを生成するテンプレートエンジンでもあります。
|
||||
|
||||
Helm is also a template engine that allows to generate config files with variables:
|
||||
## Kubernetesシークレット
|
||||
|
||||
## Kubernetes secrets
|
||||
**シークレット**は、パスワード、トークン、またはキーなどの**機密データを含む**オブジェクトです。このような情報は、Pod仕様やイメージに記載されることがあります。ユーザーはシークレットを作成でき、システムもシークレットを作成します。シークレットオブジェクトの名前は、有効な**DNSサブドメイン名**でなければなりません。こちらで[公式ドキュメント](https://kubernetes.io/docs/concepts/configuration/secret/)をお読みください。
|
||||
|
||||
A **Secret** is an object that **contains sensitive data** such as a password, a token or a key. Such information might otherwise be put in a Pod specification or in an image. Users can create Secrets and the system also creates Secrets. The name of a Secret object must be a valid **DNS subdomain name**. Read here [the official documentation](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||
シークレットには以下のようなものがあります:
|
||||
|
||||
Secrets might be things like:
|
||||
- API、SSHキー。
|
||||
- OAuthトークン。
|
||||
- 資格情報、パスワード(プレーンテキストまたはb64 + 暗号化)。
|
||||
- 情報やコメント。
|
||||
- データベース接続コード、文字列… 。
|
||||
|
||||
- API, SSH Keys.
|
||||
- OAuth tokens.
|
||||
- Credentials, Passwords (plain text or b64 + encryption).
|
||||
- Information or comments.
|
||||
- Database connection code, strings… .
|
||||
Kubernetesには異なるタイプのシークレットがあります。
|
||||
|
||||
There are different types of secrets in Kubernetes
|
||||
|
||||
| Builtin Type | Usage |
|
||||
| ビルトインタイプ | 使用法 |
|
||||
| ----------------------------------- | ----------------------------------------- |
|
||||
| **Opaque** | **arbitrary user-defined data (Default)** |
|
||||
| kubernetes.io/service-account-token | service account token |
|
||||
| kubernetes.io/dockercfg | serialized \~/.dockercfg file |
|
||||
| kubernetes.io/dockerconfigjson | serialized \~/.docker/config.json file |
|
||||
| kubernetes.io/basic-auth | credentials for basic authentication |
|
||||
| kubernetes.io/ssh-auth | credentials for SSH authentication |
|
||||
| kubernetes.io/tls | data for a TLS client or server |
|
||||
| bootstrap.kubernetes.io/token | bootstrap token data |
|
||||
| **Opaque** | **任意のユーザー定義データ(デフォルト)** |
|
||||
| kubernetes.io/service-account-token | サービスアカウントトークン |
|
||||
| kubernetes.io/dockercfg | シリアライズされた\~/.dockercfgファイル |
|
||||
| kubernetes.io/dockerconfigjson | シリアライズされた\~/.docker/config.jsonファイル |
|
||||
| kubernetes.io/basic-auth | ベーシック認証のための資格情報 |
|
||||
| kubernetes.io/ssh-auth | SSH認証のための資格情報 |
|
||||
| kubernetes.io/tls | TLSクライアントまたはサーバーのためのデータ |
|
||||
| bootstrap.kubernetes.io/token | ブートストラップトークンデータ |
|
||||
|
||||
> [!NOTE]
|
||||
> **The Opaque type is the default one, the typical key-value pair defined by users.**
|
||||
> **Opaqueタイプはデフォルトであり、ユーザーによって定義された典型的なキー-バリューペアです。**
|
||||
|
||||
**How secrets works:**
|
||||
**シークレットの動作:**
|
||||
|
||||

|
||||
|
||||
The following configuration file defines a **secret** called `mysecret` with 2 key-value pairs `username: YWRtaW4=` and `password: MWYyZDFlMmU2N2Rm`. It also defines a **pod** called `secretpod` that will have the `username` and `password` defined in `mysecret` exposed in the **environment variables** `SECRET_USERNAME` \_\_ and \_\_ `SECRET_PASSWOR`. It will also **mount** the `username` secret inside `mysecret` in the path `/etc/foo/my-group/my-username` with `0640` permissions.
|
||||
|
||||
以下の設定ファイルは、`mysecret`という**シークレット**を定義し、2つのキー-バリューペア`username: YWRtaW4=`と`password: MWYyZDFlMmU2N2Rm`を持っています。また、`mysecret`で定義された`username`と`password`が**環境変数**`SECRET_USERNAME` \_\_ と \_\_ `SECRET_PASSWOR`に公開される`secretpod`という**ポッド**も定義しています。さらに、`mysecret`内の`username`シークレットを`/etc/foo/my-group/my-username`のパスに`0640`の権限で**マウント**します。
|
||||
```yaml:secretpod.yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mysecret
|
||||
name: mysecret
|
||||
type: Opaque
|
||||
data:
|
||||
username: YWRtaW4=
|
||||
password: MWYyZDFlMmU2N2Rm
|
||||
username: YWRtaW4=
|
||||
password: MWYyZDFlMmU2N2Rm
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: secretpod
|
||||
name: secretpod
|
||||
spec:
|
||||
containers:
|
||||
- name: secretpod
|
||||
image: nginx
|
||||
env:
|
||||
- name: SECRET_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: username
|
||||
- name: SECRET_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: password
|
||||
volumeMounts:
|
||||
- name: foo
|
||||
mountPath: "/etc/foo"
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
- name: foo
|
||||
secret:
|
||||
secretName: mysecret
|
||||
items:
|
||||
- key: username
|
||||
path: my-group/my-username
|
||||
mode: 0640
|
||||
containers:
|
||||
- name: secretpod
|
||||
image: nginx
|
||||
env:
|
||||
- name: SECRET_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: username
|
||||
- name: SECRET_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysecret
|
||||
key: password
|
||||
volumeMounts:
|
||||
- name: foo
|
||||
mountPath: "/etc/foo"
|
||||
restartPolicy: Never
|
||||
volumes:
|
||||
- name: foo
|
||||
secret:
|
||||
secretName: mysecret
|
||||
items:
|
||||
- key: username
|
||||
path: my-group/my-username
|
||||
mode: 0640
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -449,114 +422,97 @@ kubectl get pods #Wait until the pod secretpod is running
|
||||
kubectl exec -it secretpod -- bash
|
||||
env | grep SECRET && cat /etc/foo/my-group/my-username && echo
|
||||
```
|
||||
|
||||
### Secrets in etcd <a href="#discover-secrets-in-etcd" id="discover-secrets-in-etcd"></a>
|
||||
|
||||
**etcd** is a consistent and highly-available **key-value store** used as Kubernetes backing store for all cluster data. Let’s access to the secrets stored in etcd:
|
||||
|
||||
**etcd** は、すべてのクラスターデータのための Kubernetes バッキングストアとして使用される、一貫性があり高可用性の **キー-バリューストア** です。etcd に保存されているシークレットにアクセスしてみましょう:
|
||||
```bash
|
||||
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd
|
||||
```
|
||||
|
||||
You will see certs, keys and url’s were are located in the FS. Once you get it, you would be able to connect to etcd.
|
||||
|
||||
あなたは、FS内にあるcerts、keys、urlを確認することができます。それを取得すると、etcdに接続できるようになります。
|
||||
```bash
|
||||
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] health
|
||||
|
||||
ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health
|
||||
```
|
||||
|
||||
Once you achieve establish communication you would be able to get the secrets:
|
||||
|
||||
一度通信が確立されると、秘密を取得できるようになります:
|
||||
```bash
|
||||
#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] get <path/to/secret>
|
||||
|
||||
ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] get /registry/secrets/default/secret_02
|
||||
```
|
||||
**ETCDに暗号化を追加する**
|
||||
|
||||
**Adding encryption to the ETCD**
|
||||
|
||||
By default all the secrets are **stored in plain** text inside etcd unless you apply an encryption layer. The following example is based on [https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
|
||||
|
||||
デフォルトでは、すべてのシークレットは**プレーン**テキストでetcd内に保存されます。暗号化レイヤーを適用しない限り。以下の例は[https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)に基づいています。
|
||||
```yaml:encryption.yaml
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key
|
||||
- identity: {}
|
||||
- resources:
|
||||
- secrets
|
||||
providers:
|
||||
- aescbc:
|
||||
keys:
|
||||
- name: key1
|
||||
secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key
|
||||
- identity: {}
|
||||
```
|
||||
|
||||
After that, you need to set the `--encryption-provider-config` flag on the `kube-apiserver` to point to the location of the created config file. You can modify `/etc/kubernetes/manifest/kube-apiserver.yaml` and add the following lines:
|
||||
|
||||
その後、作成した設定ファイルの場所を指すように、`kube-apiserver`の`--encryption-provider-config`フラグを設定する必要があります。`/etc/kubernetes/manifest/kube-apiserver.yaml`を修正し、以下の行を追加できます:
|
||||
```yaml
|
||||
containers:
|
||||
- command:
|
||||
- kube-apiserver
|
||||
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
|
||||
- command:
|
||||
- kube-apiserver
|
||||
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>
|
||||
```
|
||||
|
||||
Scroll down in the volumeMounts:
|
||||
|
||||
ボリュームマウント内をスクロールダウンします:
|
||||
```yaml
|
||||
- mountPath: /etc/kubernetes/etcd
|
||||
name: etcd
|
||||
readOnly: true
|
||||
name: etcd
|
||||
readOnly: true
|
||||
```
|
||||
|
||||
Scroll down in the volumeMounts to hostPath:
|
||||
|
||||
volumeMountsのhostPathまでスクロールします:
|
||||
```yaml
|
||||
- hostPath:
|
||||
path: /etc/kubernetes/etcd
|
||||
type: DirectoryOrCreate
|
||||
name: etcd
|
||||
path: /etc/kubernetes/etcd
|
||||
type: DirectoryOrCreate
|
||||
name: etcd
|
||||
```
|
||||
**データが暗号化されていることの確認**
|
||||
|
||||
データはetcdに書き込まれる際に暗号化されます。`kube-apiserver`を再起動した後、新しく作成または更新されたシークレットは、保存時に暗号化されるべきです。確認するには、`etcdctl`コマンドラインプログラムを使用してシークレットの内容を取得できます。
|
||||
|
||||
1. `default`名前空間に`secret1`という新しいシークレットを作成します:
|
||||
|
||||
```
|
||||
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
|
||||
```
|
||||
|
||||
**Verifying that data is encrypted**
|
||||
2. etcdctlコマンドラインを使用して、そのシークレットをetcdから読み取ります:
|
||||
|
||||
Data is encrypted when written to etcd. After restarting your `kube-apiserver`, any newly created or updated secret should be encrypted when stored. To check, you can use the `etcdctl` command line program to retrieve the contents of your secret.
|
||||
`ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C`
|
||||
|
||||
1. Create a new secret called `secret1` in the `default` namespace:
|
||||
ここで`[...]`はetcdサーバーに接続するための追加引数です。
|
||||
|
||||
```
|
||||
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
|
||||
```
|
||||
3. 保存されたシークレットが`k8s:enc:aescbc:v1:`で始まっていることを確認します。これは`aescbc`プロバイダーが結果のデータを暗号化したことを示します。
|
||||
4. APIを介して取得したときにシークレットが正しく復号化されていることを確認します:
|
||||
|
||||
2. Using the etcdctl commandline, read that secret out of etcd:
|
||||
```
|
||||
kubectl describe secret secret1 -n default
|
||||
```
|
||||
|
||||
`ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C`
|
||||
|
||||
where `[...]` must be the additional arguments for connecting to the etcd server.
|
||||
|
||||
3. Verify the stored secret is prefixed with `k8s:enc:aescbc:v1:` which indicates the `aescbc` provider has encrypted the resulting data.
|
||||
4. Verify the secret is correctly decrypted when retrieved via the API:
|
||||
|
||||
```
|
||||
kubectl describe secret secret1 -n default
|
||||
```
|
||||
|
||||
should match `mykey: bXlkYXRh`, mydata is encoded, check [decoding a secret](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret) to completely decode the secret.
|
||||
|
||||
**Since secrets are encrypted on write, performing an update on a secret will encrypt that content:**
|
||||
は`mykey: bXlkYXRh`と一致するべきです。mydataはエンコードされているため、シークレットを完全に復号化するには[シークレットの復号化](https://kubernetes.io/docs/concepts/configuration/secret#decoding-a-secret)を確認してください。
|
||||
|
||||
**シークレットは書き込み時に暗号化されるため、シークレットの更新を行うとその内容が暗号化されます:**
|
||||
```
|
||||
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
|
||||
```
|
||||
**最終的なヒント:**
|
||||
|
||||
**Final tips:**
|
||||
|
||||
- Try not to keep secrets in the FS, get them from other places.
|
||||
- Check out [https://www.vaultproject.io/](https://www.vaultproject.io) for add more protection to your secrets.
|
||||
- FSに秘密を保持しないようにし、他の場所から取得してください。
|
||||
- あなたの秘密にさらなる保護を追加するために[https://www.vaultproject.io/](https://www.vaultproject.io)をチェックしてください。
|
||||
- [https://kubernetes.io/docs/concepts/configuration/secret/#risks](https://kubernetes.io/docs/concepts/configuration/secret/#risks)
|
||||
- [https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm](https://docs.cyberark.com/Product-Doc/OnlineHelp/AAM-DAP/11.2/en/Content/Integrations/Kubernetes_deployApplicationsConjur-k8s-Secrets.htm)
|
||||
|
||||
## References
|
||||
## 参考文献
|
||||
|
||||
{{#ref}}
|
||||
https://sickrov.github.io/
|
||||
@@ -567,7 +523,3 @@ https://www.youtube.com/watch?v=X48VuDVv0do
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user