www.technotes.se » OpenBSD
Oct
23
Posted on 23-10-2010
Filed Under (Linux, OpenBSD, SSH) by Lonezor

This will make it possible to log into a machine with SSH witout manual password authentication. This is often needed for non-interactive system tasks (like pushing files to an external host for backup purposes) as well as to avoid time consuming typing of LONG passwords.

Ideally, password authentication can be disabled completely in the sshd configuration file /etc/ssh/sshd_config (PasswordAuthentication no).

1. Configure SSH server to support public key authentication in /etc/ssh/sshd_config:

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

2. Generate keys on local machine and upload the public key to the server:

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/<user>/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /<user>/.ssh/id_rsa.
Your public key has been saved in /<user>/.ssh/id_rsa.pub.
The key fingerprint is:
82:73:d5:5d:59:b4:53:aa:54:72:89:ab:fb:2d:bd:50 <user>@host-EG43M-S2H
The key's randomart image is:
+--[ RSA 2048]----+
|            ..+=+|
|         . ..=o.o|
|        . . o..o |
|     . .   ...  .|
|    o o S  .. E  |
|     o .  .  .   |
|           ...   |
|          . .o.  |
|           ...o. |
+-----------------+

$ scp /home/<user>/.ssh/id_rsa.pub <user>@<server>:/home/<user>

3. Add keys to the authentication file on the server (for the specified user):

cat /home/<user>/id_rsa.pub >> /home/<user>/.ssh/authorized_keys
rm /home/<user>/id_rsa.pub

That is it. It is now possible to use ssh and scp without manual password typing.

A note about security. Since the public key acts as a password into the other machine, it is important to make sure that access to it is restricted.

(0) Comments    Read More   
Sep
28
Posted on 28-09-2010
Filed Under (NAT, Networking, OpenBSD, port forward) by Lonezor

Starting from OpenBSD 4.7 a new packet filtering syntax is used. It is more generalized than before. This means that pf.conf needs to be translated to work properly. Typical use cases are NAT and port forwarding.

Example of the new syntax in /etc/pf.conf:

# Setup NAT for local ethernet network
ext_if = "vr0" # WAN net device
match out on $ext_if from 192.168.0.0/24 nat-to ($ext_if)

# Port forwarding, HTTP traffic
pass in on $ext_if proto tcp from any to ($ext_if) port 80 rdr-to 192.168.1.24 port 80

Load new configuration:

pfctl -f /etc/pf.conf
(0) Comments    Read More   
Sep
25

Sometimes the IP address of a net device needs to be determined programatically in cases the shell command ifconfig is not desirable. As an example, I wrote a small C program that updated the DNS records in the DNS provider’s database in the case of an IP address change.

Code example (tested on Linux and OpenBSD)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>

#define C_ASSERT(expression, name) \
typedef int c_assert_##name[-1 + (expression)]

typedef unsigned int uint32_t;
C_ASSERT(sizeof(uint32_t) == 4, uint32_t);

#define IP_UNDEFINED 0

uint32_t get_ip_addr_for_device(char* net_device_p)
{
  struct ifreq ifr;
  struct sockaddr_in* sock_addr_p = NULL;
  int ctrl_socket = -1;
  uint32_t ip_addr = 0;
  int res = -1;

  ctrl_socket = socket(AF_INET, SOCK_DGRAM, 0);
  if (-1 == ctrl_socket) {
    perror("get_ip_addr_for_device, socket");
    goto cleanup;
  }

  memset(&ifr, 0, sizeof(ifr));
  ifr.ifr_addr.sa_family = AF_INET;
  strncpy(ifr.ifr_name, net_device_p , IFNAMSIZ);

  res = ioctl(ctrl_socket, SIOCGIFADDR, &ifr); /* Query IPv4 address */
  if (-1 == res) {
    perror("get_ip_addr_for_device, ioctl (SIOCGIFADDR)");
    goto cleanup;
  }

  sock_addr_p = (struct sockaddr_in *) &ifr.ifr_addr;
  memcpy(&ip_addr, &sock_addr_p->sin_addr.s_addr, 4);

cleanup:
  if (ctrl_socket != -1) {
    close(ctrl_socket);
  }
  return ip_addr;
}

static void print_ip_addr(uint32_t ipv4_addr)
{
  unsigned char* ip_addr = (unsigned char*) &ipv4_addr;
  printf("IP address: %d.%d.%d.%d\n",
   ip_addr[0],
   ip_addr[1],
   ip_addr[2],
   ip_addr[3]);
}

int main(int argc, char* argv[])
{
  uint32_t ip_addr = 0;

  if (1 == argc) {
    printf("usage: ip_checker NET_DEVICE\n");
    goto exit;
  }
  else if (argc < 2) {
    printf("ip_checker: too few arguments!\n");
    goto exit;
  }

  ip_addr = get_ip_addr_for_device(argv[1]);

  if (IP_UNDEFINED != ip_addr) {
    print_ip_addr(ip_addr);
  }

exit:
  return 0;
}

Usage example

$ gcc -Wall ip_checker.c -o ip_checker
$ ./ip_checker eth0
IP address: 192.168.0.42
(1) Comment    Read More