# Client-based Access to Services

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/user/cli/access>.

## Overview

Once you're connected to the *Cluster* (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md)), you can access a *Service* using its private hostname or full FQDN. For example, you might first want to list all the available *Services* in the *Cluster* (read more [here](https://octelium.com/docs/octelium/latest/user/cli/overview.md#listing-resources)) as follows:

```bash
export OCTELIUM_DOMAIN=example.com

octelium get service
# OR simply
octelium get svc

# You can also list Services in a certain Namespace
octelium get svc --namespace default
# Another example
octelium get svc -n production
```

The output of the command above should give your the list of the available *Services* in your *Cluster*. Here is an example:

```bash
        NAME       | NAMESPACE | PORT | TYPE |         ADDRESSES          |          DESCRIPTION           | TLS  | PUBLIC  
-------------------+-----------+------+------+----------------------------+--------------------------------+------+---------
  demo-nginx       | default   |   80 | WEB  | 100.64.0.23, fdee:e801::17 | A Demo nginx server that       |      | True    
                   |           |      |      |                            | is deployed as a managed       |      |         
                   |           |      |      |                            | container and accessible by    |      |         
                   |           |      |      |                            | all Users                      |      |         
                   |           |      |      |                            | dashboard                      |      |         
  essh             | default   |   22 | SSH  | 100.64.0.34, fdee:e801::22 |                                |      |         
  pg2              | default   | 5432 | TCP  | 100.64.0.36, fdee:e801::24 |                                |      |         
  nginx            | default   |   80 | WEB  | 100.64.0.38, fdee:e801::26 |                                |      | True    
  code             | default   | 8080 | WEB  | 100.64.0.43, fdee:e801::2b |                                |      | True    
  ssh-h01          | default   |   22 | SSH  | 100.64.0.42, fdee:e801::2a |                                |      |         
```

## Addressing a Service

### Hostname

As discussed above, you access a *Service* using its private hostname, simply the *Service* name as shown in the `NAME` column of the output of the `octelium get svc` command. For example, the `demo-nginx` in the list above is a `WEB`, basically an HTTP-based *Service*. This *Service* is listening over the standard HTTP port `80`. You can simply access it via curl or your browser at the URL `http://demo-nginx`. Here is an example:

```bash
curl demo-nginx
```

### FQDN

You can also use the entire private FQDN of the *Service* as follows:

```bash
curl demo-nginx.local.<DOMAIN>
```

### Namespaces

For *Services* that belong to *Namespaces* other than the `default` *Namespace* (read more about *Namespaces* [here](https://octelium.com/docs/octelium/latest/management/core/namespace.md)), you can address them via the hostname `<SERVICE_NAME>.<NAMESPACE_NAME>`. For example, if you have an `nginx` *Service* in the `production` *Namespace*. You can access it as follows:

```bash
curl nginx.production
```

And you can also use its full private FQDN as follows:

```bash
curl nginx.production.local.<DOMAIN>
```

> **Note:**
>
> While Octelium's private DNS Server can resolve hostnames of *Services* belonging to *Namespaces* other than `default` (e.g. `nginx.production`), it is always much more recommended to use the full private FQDN whenever possible.

### IP Address

And you can also directly access the *Service* via its private IPv6 or IPv4 IP addresses. For example, you might have to directly use the IP addresses if you're disabling the *Cluster* private DNS Server via the `--no-dns` flag in the `octelium connect` command (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#dns)). By default, `octelium connect` usually uses IPv6-only tunneling when connected to the *Cluster*. Here is an example:

```bash
curl 'http://[fdee:e801::17]'
```

If your `octelium connect` command is enabling IPv4 (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#layer-3-mode)), then you can access the *Service* as follows:

```bash
curl http://100.64.0.23
```

## Mapping a Service to Localhost

You can also publish, or simply map, a certain *Service* to your localhost when you connect to the *Cluster* via the `-p` or `--publish` flag (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#mapping-services-to-host)). Here is an example:

```bash
octelium connect -p demo-nginx:8000
```

In such case, you can simply access the `demo-nginx` as follows:

```bash
curl localhost:8000
```

> **Note:**
>
> Accessing *Services* through mapping them to localhost is the only way possible to access *Services* when connecting to the *Cluster* via the rootless mode (i.e. using `octelium connect` as an unprivileged/non-root OS user). You can read more about the rootless mode for `octelium connect` [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#rootless).

## Applications

### Kubernetes

For `KUBERNETES`-based *Services*, you can use standard `kubectl`. Unlike most clients, however, `kubectl` does not address clusters by their domains; it relies entirely on a kubeconfig file. Octelium therefore provides the `octelium config` (or simply `octelium cfg`) command to automatically generate a kubeconfig for any `KUBERNETES`-based *Service* in the *Cluster*. For example, if your *Service* is called `k8s-01`, you can set up the kubeconfig as follows:

```bash
octelium cfg k8s-01
```

The output of the command above should look as follows:

```bash
Set the following environment variable to use kubectl commands for the Service k8s1:
export KUBECONFIG=/home/<YOUR_OS_USER>/.kube/k8s-01.<DOMAIN>
```

Now you just need to set the environment variable shown to you and start using your `kubectl` commands as follows:

```bash
export KUBECONFIG=/home/<YOUR_OS_USER>/.kube/k8s-01.<DOMAIN>
kubectl get pods -A
```

### SSH

For `SSH`-based *Services*, you can simply use the standard OpenSSH client. For example, there is a `ssh-h01` `SSH`-based *Service* in the list above, we can access it simply as follows:

```bash
ssh ssh-h01
```

The `ssh-h01` above is listening over the standard SSH port `22`. If it is listening over some custom port number, e.g. `2022`, we can simply use `-p` flag as follows:

```bash
ssh -p 2022 ssh-h01
```

### PostgreSQL

For `POSTGRES`-based *Services*. You can, for example, use the standard `psql` CLI as follows:

```bash
psql -h my-postgres-db-1
```

### MySQL

For `MYSQL`-based *Services*. You can, for example, use the `mysql` CLI as follows:

```bash
mysql -h mysql-db-1
```

If the *Service* is serving on a non-standard port number (i.e. other than `3306`), you can access the database as follows:

```bash
mysql -h mysql-db-1 -P 3456
```

> **Note:**
>
> You currently have to keep the password as an **empty** value to access the `MYSQL` *Service*.

### SOCKS5

For `SOCKS5`-based *Services* (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/socks5.md)), you can use any standard SOCKS5-capable client. For example, you can use `curl` with its `--socks5` flag to reach a destination through the proxy as follows:

```bash
curl --socks5 socks5-svc:1080 https://checkip.amazonaws.com
```

#### Embedded SOCKS5

Octelium provides a built-in `socks5.octelium` *Service* that operates in embedded SOCKS5 mode (read more [here](https://octelium.com/docs/octelium/latest/management/core/service/socks5.md#embedded-mode)). This enables you to reach the embedded SOCKS5 proxy served from within a connected *Session*, instead of proxying to a standalone SOCKS5 server. A *Session* serves embedded SOCKS5 by connecting to the *Cluster* with the `--esocks5` flag as follows:

```bash
export OCTELIUM_DOMAIN=example.com
octelium connect --esocks5
```

Now, you reach the embedded SOCKS5 proxy of a certain *Session* by using the *Session*'s name as the SOCKS5 username. For example, you can first list the current *Sessions* as follows:

```bash
octeliumctl get sess
```

Once you obtain the *Session* name (e.g. `root-8igx2u`), you use it as the SOCKS5 username against the `socks5.octelium` *Service* as follows:

```bash
curl --socks5 root-8igx2u@socks5.octelium:1080 https://checkip.amazonaws.com
```

In this case, the connection to the final destination originates from the host running the `octelium` client of that *Session*.

### Embedded SSH

If you want to access an embedded SSH *Service* (read more about embedded SSH [here](https://octelium.com/docs/octelium/latest/management/core/service/embedded-ssh.md)), you need to specify the name of the **connected** *Session* as the SSH user. For example, you can list the available *Cluster*'s *Sessions* as follows:

```bash
octeliumctl get session
#or simply
octeliumctl get sess
```

The output of the command above should look as follows:

```bash
     NAME     | USER |         TYPE         | EXPIRES IN | AGE  | STATE  | CONNECTED  
--------------+------+----------------------+------------+------+--------+------------
  root-zxklxg | root | CLIENT               | 83d        | 6d6h | ACTIVE |            
  usr1-9o2ztp | usr1 | CLIENT               | 83d        | 6d5h | ACTIVE | True       
  usr1-pv0mo9 | usr1 | CLIENTLESS (Browser) | 157m       | 13h  | ACTIVE |            
```

Now, we see that the `usr1-9o2ztp` *Session* is connected. Now, assuming that our embedded SSH *Service* has the name `essh` in the `default` *Namespace*, if that *Session* is explicitly serving embedded SSH via the `--essh` flag (read more [here](https://octelium.com/docs/octelium/latest/user/cli/connect.md#serving-embedded-ssh)), then we can simply SSH into that *Session*'s host as follows:

```bash
ssh usr1-9o2ztp@essh
```

The *Cluster* also comes with a built-in `essh.octelium` *Service* that operates in embedded SSH mode, so you can SSH into the host of a connected *Session* without having to create your own embedded SSH *Service*:

```bash
ssh usr1-9o2ztp@essh.octelium
```

The `octelium ssh` command acts as an embedded SSH client inside the `octelium` binary that enables you to open an interactive SSH session or execute a remote command on a connected Octelium *Session* using its name if the *Session* is enabling the `--essh` flag when connecting to the Cluster. Here are some examples:

```bash
# Open an interactive shell
octelium ssh john-abcdef

# Run a single remote command
octelium ssh john-abcdef -- uptime

# Run a shell pipeline
octelium ssh john-abcdef -- sh -c "ps aux | grep python"

# Local port forward: forward local :5432 to remote localhost:5432
octelium ssh john-abcdef -L 5432:localhost:5432

# Multiple port forwards, no interactive shell
octelium ssh john-abcdef -N -L 5432:localhost:5432 -L 6379:localhost:6379

# Dynamic SOCKS5 proxy on local port 1080
octelium ssh john-abcdef -D 1080 -N
```

The `octelium cp` command enables you to copy files or directories between the local filesystem and remote filesystems of connected Octelium *Sessions*, or between two connected *Sessions* that are enabling the `--essh` flag when connecting to the *Cluster* via `octelium connect`. Here are some examples:

```bash
# Copy a local file to a session
octelium cp ./config.json john-123456:/home/user/config.json

# Copy a file from a session to local
octelium cp john-123456:/home/user/output.csv ./output.csv

# Copy a local directory to a session
octelium cp -r ./src/ john-123456:/home/user/src/

# Copy a directory from a session to local
octelium cp -r john-123456:/home/user/dist/ ./dist/

# Copy a file from one session to another
octelium cp john-123456:/home/user/data.json linus-abcdef:/home/user/data.json

# Copy a directory from one session to another
octelium cp -r john-123456:/home/user/data/ linus-abcdef:/home/user/data/
```

## TLS

For *Services* that are listening over TLS, you should use the full private FQDN of the *Service*. For example, if the *Service*`nginx` belonging to the `default` *Namespace* is TLS-enabled and listening over the standard port `443`, then you can access it as follows:

```bash
curl https://nginx.local.<DOMAIN>
```
