Open Build System(OBS)で依存関係のソースのリポジトリを指定する

普段、サーバでNAXSIというWeb Application Firewallを使ってるので、せっかくだからディストリビューション開発もくもく会に参加したので、勢いでOBSにリポジトリを作ってみました。 作ったリポジトリがhttps://build.opensuse.org/package/show/home:Manami:nginx-modules/nginx-module-naxsiです。

この際に困ったのが、Nginxのバージョンです。Nginxには公式のリポジトリで提供されている安定版とOBSのServer:httpで提供されている最新版があって、Server:httpではNginxのいろいろなモジュールが公開されていることから、自分は後者を使っています。ところが、普通にSpecファイルでBuildRequiresを書くと安定版のNginxを使用されます。それだと実際にインストールしようとした時にバージョンが違うとコンフリクトを起こすので困ります。そこで、特定のリポジトリから提供されているパッケージを使用してほしいのですが設定にやや戸惑ったので記録しておきます。

まず、リポジトリのページに行き、”Repositories”に移動し、”You can configure individual flags for this package here. The repositories are inherited from the project (Repository Name)”の(Repository Name)のリンクをクリックします。
すると、以下の様に追加したターゲットのRepository pathsが表示されているので、各た0ゲットの”+”ボタンをクリックします。

そこで、リポジトリ名をいれるところがでるので、”server:http”とか”Virtualization”などいれます。Repositoryはターゲットのバージョンに合わせて選びます。

これで、Acceptを押せば、追加されるので、追加されたパスの横にある”↑”ボタンを押して優先度を上げてやれば完了です。

残念ながらプロジェクト毎の調整はできないみたいですが、OBSにはサブプロジェクトというものがあるそうです。(クロスディストロの方々に教えていただきました。)

“Your Home Project”をクリックして、”Overview”の欄にある”Subprojects”をクリックして、右側の”Actions on this page”にある、”Create subproject”をクリックして適宜作ってください。

あと、先にビルドしちゃうとこの変更に伴う再ビルドはされないみたいなのでファイルのアップデートやRelease番号のインクリメントなどで対応してみてください。

将来の夢とか何とか

最近ブログを書いてなかったな〜などと思いながら過ごしてたらGWが終わりかけていた。
相変わらず精神状態は上向かず、ただ極端に下向くことはなくで生きている。
GWもさんざん遊んだのにもかかわらず「楽しい!」と思ったことがなく「これは楽しい事なんだよ」と思いこんで少し心が楽になったりならなかったりそんなことをしていた。
新しい病院に言ったら、心理検査を受けて、「ASDのボーダーラインでADHDのグレーゾーンですね」なんて言われて微妙な気持ちになってそれも未だに引きづっていたり…

追記(2023/05/16):昨日、主治医さんと長く話すことが出来き、心理検査の結果を見せてもらったWAIS-IVの結果は、語彙・言い換え・暗算が平均ラインを上回り、暗唱・記号転写などワーキングメモリを測る項目が平均ラインを下回って凸凹していた。コミュニケーションなどの自閉傾向を測るテスト(AQだったような)はすべての項目がカットオフポイント以上であり自閉傾向が強いと出て、タスク管理と人とのコミュニケーションはうまく向き合って行かないといけないということがわかった。

さて、皆さん将来の夢ってなんだろうか。
子供の頃、周りがケーキ屋さんなどとキラキラした目で語っていた横で、表では車掌などと行っておきながら、内面では貧困に苦しみたくないと漠然と思っていた。その頃家庭で収入がなく苦しんでいたのもあるかもしれない。中学の頃からは将来の夢というものを何も考えなくなってきていた。
ゆるふわな将来の夢から人生設計図というものを書くよう求められる年代になって、自分は大学卒業後の進路を全く書くことがなかった。周りは2X歳で結婚・出産などと語ってる中で、自分は果たして年金開始は65歳なのか70歳なのか、それともさらに後になるのかなどを憂いていた。将来というものに単純に興味がなかったというか、大人になるという事に何の夢もなかった。まるで別世界の話のごとく自分には縁がないかのように思っていた。
そんな事を置いておいてプログラミングや動画制作などにひたすら励み、思いつく事をひたすらに具現化していっていたら時は過ぎ、貧困は嫌なので勉学には励んだ。
プログラミングは幸いにも技術が伸びていき、イベント参加を通して、人と関わっておおくの知識を得たいと思うようになった。後に大学を関東圏にしたいという希望が出て来る。

無事、関東の大学に行きさまざまなイベントに参加したのも束の間、新型コロナウイルス感染症が流行しだし、全てのやりとりはオンラインとなり、イベントごとも無くなった。実家に引きこもりそうこうしているうちに、大学生活が過ぎて行った。
このころから更に物事に関する関心が低下していき、消極的になっていった。
その後、なんやかんやあって双極性障害を発病し、脳のリソースが制限され(今までコードをガリガリかけていたのは躁状態だったのかもしれない)、うまくプログラミングができなくなった。そんでもって、将来の夢はプログラマーというのにも疑念が出てきた。
それとは別に将来のことも真面目に考えないといけなくなった。1人暮らしをして気が付いたが、自分は一人で部屋にこもっているのが苦手らしい。元々低い自己肯定感が更に低くなって、人間の本能というか恥ずかしいものだな、俗っぽいものだなと思いながら、誰か存在を肯定してくれる人がいるといいな、と思うようになった。それでは相手を見つけないといけないということになるが、そんな能力は持ち合わせてなかった。それでは、一人で生きていくという事をしなければならないが、正直自己肯定感の低い自分にエサをやり続けるために働くというのが何とも言えない感覚がある。こんな自分に価値はあるのだろうかと自問している間が何とも辛い。

趣味にしてもプログラミングが一人で自走できる趣味だったので、これができなくなると一人でやる趣味というのがなくなって、他人から声をかけてもらうのを待っている。なかなか1人ではやる気が起きず、それでもって声がかかったタイミングでは体調が悪かったりと土日は布団の上でボーっとしていることが多い。旅も段々疲れて気力がそがれるし、観光地を見ても何も感じなくなってきた。(これは鬱のせいかもしれない。)
やることがなく、土日を過ごすことは平日の張りも失って、淡々と生きている感じがある。

本当は色々書きたいのだが、とにかく根気というものがそがれてだらだらと文章を書く気力もない。
自分は社会人をやっていけるのだろうか、支えあえる人を見つけられるのだろうか、一人ならその暮らしに耐えられるだろうか、今日も漠然とした不安を抱えて夜を過ごす。

Ethernetで一対一でデバイスと通信

ルータなどを介さずにIoTデバイスと直接やり取りする場合に必要な設定などを記録しておきます。
具体的に言うと、本来は IoT Device <—> Router <—> PCと通信するものをIoT Device <–> PCと通信する場合に必要に設定です。環境はopenSUSEを想定しています。

まずdhcp-serverをインストールします。その後設定を以下のように書き換えます。
なお、今回IoT Deviceに割り当てるIPアドレスレンジは192.168.0.2 ~ 192.168.0.100までとし、PC側のIPv4アドレスは192.168.0.1とします。また使用するネットワークインターフェイスの名前は”enp1s0f1″とします。また必要に応じてfirewalldは落としておいてください。

“/etc/dhcpd.conf”に以下のように設定します。

option subnet-mask 255.255.255.0;
subnet 192.168.0.0 netmask 255.255.255.0 {
        range 192.168.0.2 192.168.0.100;
}

次に”/etc/sysconfig/dhcpd”に使用するネットワークインターフェイスを指定します。

DHCPD_INTERFACE="enp1s0f1"

IPコマンドでIPアドレスレンジを割り当ててからDHCPサーバを起動します。

sudo ip addr flush dev enp1s0f1
sudo ip addr add 192.168.0.1/24 dev enp1s0f1
sudo systemctl start dhcpd

IoT DeviceがARPに対応していてIPアドレスの問い合わせのブロードキャストに対して適切に応答してくれる場合はいいんですが、無視してしまうようなデバイスの場合IPアドレス直指定で通信してもPCの方がARPパケットを飛ばしまくって結局通信できない、ということになります。
その場合、無理やりパケットがIoT Deviceに到達するように調整します。

IoT DeviceとのDHCPでのやり取り(Discover・Request・ACK)の中でIPアドレスとMACアドレスがわかるはずなのでそれを記録しておいてください。もしくはデバイスに記載されている場合はそちらを参照してください。
ipコマンド群を実行する前にIoTデバイスのIPアドレスとMACアドレスを変数として以下のように定義しておいてください。

IOT_IP_ADDRESS=192.168.0.2
IOT_MAC_ADDRESS=00:00:5E:00:53:11

DHCPによるIoT DeviceのIPアドレス取得が完了したの見計らってDHCPサーバを停止し、ipコマンドでネットワークの調整を行います。以下のコマンドを実行していきます。

sudo systemctl stop dhcpd
sudo ip addr flush dev enp1s0f1
sudo ip addr add 192.168.0.1/24 dev enp1s0f1
sudo ip route add ${IOT_IP_ADDRESS} dev enp1s0f1
sudo ip neigh add ${IOT_IP_ADDRESS} dev enp1s0f1 lladdr ${IOT_MAC_ADDRESS}

これでARPを飛ばさずにMACアドレスとIPアドレス直指定でIoT Deviceと通信できるようになるはずです。

openSUSEデスクトップ環境設定Etc

久しぶりにopenSUSEのほうをいじったら動かなくなったので色々動かなくなっていたので設定し直した時の備忘録

KDEでIBusが起動しない

~/.config/autostart/にibus-autostart.desktopなどで以下を作成

[Desktop Entry]
Comment[ja_JP]=Start IBus daemon
Comment=Start IBus daemon
Exec=/usr/bin/ibus-daemon -rxR
GenericName[ja_JP]=IBus Daemon
GenericName=IBus Daemon
Icon=ibus-setup
MimeType=
Name[ja_JP]=IBus
Name=IBus
Path=
StartupNotify=false
Terminal=false
TerminalOptions=
Type=Application
Version=1.0
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-GNOME-Autostart-Delay=10
X-KDE-StartupNotify=false
X-KDE-SubstituteUID=false
X-KDE-Username=
X-KDE-autostart-after=panel

手癖で/usr/bin/ibus-daemon -drxRとしていたけど、それはコマンドラインから起動させる場合であってautostartでは”-d”はいらない。

PulseAudioじゃなくてPipeWireを使う

ヘッドホンのコーディックがHFPしか選択できず、音質に耐えられなかったのでごにょごにょしてたら、最近はPulseAudioじゃ無くてPipeWireを使うらしいというわけで以下を実行

Remove: pulseaudio pulseaudio-lang pulseaudio-module-* alsa-plugins-pulse mpg123-pulse pulseaudio-bash-completion pulseaudio-setup pulseaudio-zsh-completion system-user-pulse pulseaudio-utils

Install: pipewire pipewire-moudles-*  pipewire-alsa pipewire-pulseaudio  bluez-auto-enable-devices libdac2 libpulse0 libsbc1 gstreamer-plugin-pipewire

そんでもって一応以下のコマンドを実行

sudo mkdir -p /etc/pipewire/media-session.d/ && sudo touch /etc/pipewire/media-session.d/with-pulseaudio

再起動すると結構豊富にコーディックプロファイルが選べるようになっていた。

アセンブリでラベルを関数として認識させる

OS自作などでアセンブリでなにかの処理を書いた後に、これをCやRustなどから呼び出すことがあると思います。
このようなことをしている時に稀にリンカが超巨大エラーメッセージを吐いてズッコケることがありませんか?私はあります。
さて、このエラーをチンタラ解読するとアセンブリで書いた関数が再配置で呼び出し元の関数と離れすぎて相対ジャンプできないんだけど、みたいなことが書いてあります。例えば以下のようなエラーを吐いている場合などです。

relocation R_X86_64_PLT32 out of range: -549755221402 is not in [-2147483648, 2147483647]

「じゃあアセンブリの関数を呼び出し元の近くに配置してくれればええやんけ…」と思ってもやってくれないので、どうにかするしかないわけです。

手始めにstripなどされてないバイナリをobjdump -xでアセンブリのラベルがどう認識されているかを調べてみます。
アセンブリで

.section .text
hoge: 
        mov rax, rdi
        mul rdi
        ret

などと書いたとします。
すると、objdump -xでは
ffffff8000100000 l .text 0000000000 hoge
などと表示されます。
ここでCやRustで書かれた関数を見ると
ffffff8000200000 l F .text 000000003f foo
という感じの表示になっています。

さて、違いを見比べるとアセンブリで書いた関数は「Fのマークがない」「サイズが0」という点が異なるとわかります。特にサイズが0だと言うことはリロケーションができそうになさそうです。これで関数の再配置ができなくてリンカがコケるのではないかと思うわけです。
ここでアセンブリのラベルを高級言語での関数と同等の表示がされるようにしてみます。

まずは、「F」のマークをつけたいと思います。おそらく「Function」の略でしょうが、これは単に.textセクションに置くだけではつかないようです。
ここでELF形式で出力する場合は、.typeという擬似命令を使用できます。hogeの上に.typeを追加してみます。

.section .text
.type    hoge, %function
hoge: 
        mov rax, rdi
        mul rdi
        ret

これで再度objdumpの結果を見てみると
ffffff8000100000 l F .text 0000000000 hoge
などと表示されているはずです。ひとまずは関数として認識させられたようです。

問題は関数のサイズをどう認識させるかです。これがないと、どこまでがhogeなのかがリンカからわかりません。
ネットを探し回っていると.sizeという擬似命令を見つけました。
これは
.size label_name, size
label_nameのサイズをsizeであると指定する命令のようです。
これでsizeにhogeのretまでのバイト数を明記すれば良さそうです。
ただ、毎度計算するのは面倒なので”.“を使って、楽をします。

.section .text
.type    hoge, %function
hoge: 
        mov rax, rdi
        mul rdi
        ret
.size   hoge, . - hoge

.“は現在のアドレスを示すので、関数の先頭のアドレスを示すラベルとの引き算で関数のサイズが計算できます。

これでビルドしてobjdumpの結果を見ると、
ffffff8000100000 l F .text 0000000007 hoge
というふうにサイズもしっかり記載されてます。
これでhogeがリロケーションされ呼び出し元の近くに配置してリンカのエラーがなくなることもあります。(別のことが原因の場合もある)

この記事の元ツイート: https://twitter.com/PG_MANA_/status/1550674356929724416

Mini Web ServerをC言語で書いた

自作OSでopenとかreadのSystemCallを実装していましたが、何か面白いものを作りたくなったので、最近の自作OSでは一つの目標(?)とされているWebサーバを動かすことを目標とすることにしました。
とりあえず使用するシステムコールを探るためにC言語で超簡易版のWeb Serverを書いてみました。

使用するSystemCallを最小限にするためにfopenやmallocなどは使用せず、open/readなどのSystemCallに近い関数のみ使用するようにしました。本当はmallocは既にOS側でメモリ管理ができているので使いたかったのですがこの世のLinux向けのlibc実装はメモリを確保する際にbrkやmprotectを使用するらしく、現在の自分のOSでは紆余曲折あってLinux ABI互換で、これらの実装がやや面倒だったので(頑張ればできないことはないが)、とりあえず端折ることにしました。

コードは以下のとおりです。

#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

//#define DEBUG

#ifdef DEBUG
#include <arpa/inet.h>
#endif

#define HTTP_VERSION "HTTP/1.1"
#define GET_METHOD "GET"
#define SERVER_HEADER_ENTRY "Server: Mini Web Server"
#define HTTP_200 HTTP_VERSION " 200 OK"
#define HTTP_404 HTTP_VERSION " 404 Not Found"
#define HTTP_500 HTTP_VERSION " 500 Internal Server Error"

int main() {
  puts("Mini Web Server");

  int receive_socket = socket(AF_INET, SOCK_STREAM, 0);
  if (receive_socket < 0) {
    fprintf(stderr, "Failed to open the socket(ret: %d)\n", receive_socket);
    return 1;
  }

  struct sockaddr_in host;
  host.sin_family = AF_INET;
  host.sin_port = htons(8080);
  host.sin_addr.s_addr = INADDR_ANY;
  if (bind(receive_socket, (struct sockaddr *)&host, sizeof(host)) < 0) {
    fprintf(stderr, "Failed to bind\n");
    return 1;
  }

  if (listen(receive_socket, 10) < 0) {
    fprintf(stderr, "Failed to listen the socket.\n");
    return 1;
  }

  while (1) {
    struct sockaddr_in client_address;
    socklen_t client_address_length;
    int client_socket =
        accept(receive_socket, (struct sockaddr *)&client_address,
               &client_address_length);
#ifdef DEBUG
    printf("Client: {\"Address\": \"%s\", \"Port\": %d}\n",
           inet_ntoa(client_address.sin_addr), client_address.sin_port);
#endif
    char buffer[0x1000];
    buffer[sizeof(buffer) - 1] = '\0';

    int received = recv(client_socket, buffer, sizeof(buffer), 0);
    if (received < 0) {
      fprintf(stderr, "Failed to receive data(ret: %d)\n", received);
      return 1;
    }

    /* Check method */
    if (received <= (sizeof(GET_METHOD) - 1) ||
        strncmp(buffer, GET_METHOD, sizeof(GET_METHOD) - 1) != 0) {
      close(client_socket);
      continue;
    }
    size_t pointer = sizeof(GET_METHOD) - 1;

    if (buffer[pointer] != ' ' || buffer[pointer + 1] != '/') {
      close(client_socket);
      continue;
    }
    pointer += 1;
    /* remove "/"(root) */
    pointer += 1;
    char *file_name = buffer + pointer;
    size_t file_name_size = 0;
    for (; (pointer + file_name_size) < received &&
           buffer[pointer + file_name_size] != ' ';
         file_name_size++)
      ;
    pointer += file_name_size + 1;

    if (received <= (pointer + sizeof(HTTP_VERSION) - 1) ||
        strncmp(buffer + pointer, HTTP_VERSION, sizeof(HTTP_VERSION) - 1) !=
            0) {
      close(client_socket);
      continue;
    }
    if (file_name_size == 0) {
      const char index_name[] = "index.htm";
      strcpy(file_name, index_name);
      file_name_size = sizeof(index_name) - 1;
    }
    file_name[file_name_size] = '\0';
#ifdef DEBUG
    printf("URL: %s\n", file_name);
#endif
    /* Create Response */
    int fd = open(file_name, O_RDONLY);
    if (fd < 0) {
      const char not_found_text[] =
          HTTP_404 "\r\n" SERVER_HEADER_ENTRY "\r\n\r\nFile is not found.";
      send(client_socket, not_found_text, sizeof(not_found_text) - 1, 0);
    } else {
      size_t size = lseek(fd, 0, SEEK_END);
      lseek(fd, 0, SEEK_SET);
      if (size > sizeof(buffer)) {
        const char error_text[] =
            HTTP_500 "\r\n" SERVER_HEADER_ENTRY
                     "\r\n\r\nFile size is exceeded the buffer size.";
        send(client_socket, error_text, sizeof(error_text) - 1, 0);
      } else {
        sprintf(buffer,
                HTTP_200 "\r\n" SERVER_HEADER_ENTRY
                         "\r\nContent-Length: %zu\r\n\r\n",
                size);
        send(client_socket, buffer, strlen(buffer), 0);
        read(fd, buffer, size);
        send(client_socket, buffer, size, 0);
      }
    }
    close(client_socket);
  }
  return 0;
}

straceで呼ばれているシステムコールを確認すると起動処理以外では、

  • wrtiev(puts, fprintf)
  • socket
  • bind
  • listen
  • accept
  • recvfrom
  • open
  • lseek
  • sendto
  • read
  • close

のみとなってます。

とりあえずLinuxでビルドしたところまあまあ動いているようのなのでこれが動くように頑張ります。

と言っても、まずはネットワークデバイスのドライバ書くところから始めないといけないのですが…

追記: 一応動きました。 https://twitter.com/PG_MANA_/status/1533812030582292481

MouseProのLTEモジュール(Telit LN940)をLinuxで使う(ATコマンド編)

旅先や出先で大活躍のLTEモジュール付きノートパソコンですが、妙に電波のつかみが悪いので更に調査していたところ別の方法で認識させることができたので記録しておきます。

環境

  • MousePro-NB510HL
  • openSUSE Tumbleweed
  • KDE Plasma Desktop

注意

前回の方法(MouseProのLTEモジュール(Telit LN940)をLinuxで使う)をすでに適用されている場合は一旦取り消して再起動してください。
具体的には以下のコマンドを実行してください。

sudo rm /etc/udev/rules.d/15-lte.rules
sudo systemctl disable wwan-sleep-hook
sudo rm /etc/systemd/system/wwan-sleep-hook.service

また今回の方法はモジュールのファームウェアの設定を変更します。そのため場合によってはモジュールが動作不能になる恐れがあります。以下の内容は全て自己責任で行ってください。

手順

まずはlibqmiやmodemmanagerをインストールします。
ModemManagerは起動させずに停止させたままにします。
(sudo systemctl stop ModemManager)

次に/dev/ttyUSB2に接続します。(screenコマンドがない場合はインストールしてください)

sudo screen /dev/ttyUSB2 115200

接続したらATE1と入力し改行します。(アルファベットは大文字で)、リターンキーを押すまでエコーバックはないのでお気をつけください。この作業でエコーバックを有効にします。成功すればOKと返ってきます。

(ATE1と入力し改行)
OK

次にATIと入力し改行してみます。成功すれば各情報とOKが返ってきます。(改行)はリターンキーのことを指します。

ATI(改行)

Manufacturer: QUALCOMM INCORPORATED
Model: 4105
Revision: (ファームウェアのリビジョン番号)
+GCAP: +CGSM

OK

モデルが4105であることを確認し次の作業に進みます。
AT^SETMODE?で現在のファームウェアの状態を確認します。成功すれば現在のファームウェアのモードとOKが返ってきます。マニュアルによれば0がNormal Mode、1がExtension Mode、2がLegacy Modeだそうです。

AT^SETMODE?(改行)
^SETMODE: 0

OK

次にモードを1(Extension Mode)に変更します。
AT^SETMODE=1でモードを変更します。成功すればOKが返ってきます。

AT^SETMODE=1
OK

ここまで来たらCtrl+a, k, yの順に入力しscreenを終了し、最後に再起動します。


再起動後ModemManagerを起動するとKDEのネットワーク設定でLTEモジュールを認識していることを確認します。
あとはMouseProのLTEモジュール(Telit LN940)をLinuxで使うを参考にKDEの設定を行ってください。
まれに接続が成功してもDNSの名前解決ができない場合があります。(curl https://1.1.1.1/ は接続できるけど curl http://example.com はできないなど)
この際は、resolv.confにPublic DNSを追記してやると接続できるようになる場合があります。

sudo sh -c "echo nameserver 1.1.1.1 >> /etc/resolv.conf"

以上の方法でusb_switchを使う場合よりより安定してつながるようになりました。
もし、不具合が発生した場合は上記の手順をAT^SETMODE=0に変更して行えば元に戻るはずです。

あけましておめでとうございます

今年もあけてしまったらしいです。新型コロナウイルス感染症もあってか2020から時の進みが速い気がします。

去年は東京に戻って引っ越しをしたり、またまた実家に帰ったり、お仕事を頂いたり、本の謝辞に載せていただいたりと色々なことがありました。とても貴重な体験でした。それでもオフラインの勉強会やイベントに参加することはかないませんでしたが…

初日の出を見て写真を撮り、飛行機で東京に戻るところです。元旦は妙に飛行機が安くて助かります(?)

年越しはOS自作をやっておりました。今年少しずつ進めていければと思います。

今年もよろしくおねがいします。

Linuxディストリビューションの比較

なかなかWordPressが完璧に動かないで悩んでいたら、いつの間にか動くようになっていて気がついたら、8月が終わってしまいました。
何かあるたびにログ見て悩むのはめんどくさいですが楽しくもありますよね。

今回はとりあえず、今まで扱ってきたことのあるLinuxディストリビューションについてざっと特徴をまとめてみたいと思います。
注意してもらいたいことは、Linuxディストリビューションとデスクトップ環境(GNOMEやKDE)というのは別物であり、それぞれのディストリビューションで対応していたりしていなかったりするのでご注意ください。
2021/04/06 追記: 最近アクセス数が増えておりますが、内容はあくまで個人的な意見ということをご留意ください。

2017/09/30:編集
2018/09/07:編集
2020/01/31:編集
2020/10/25:編集
2021/04/06:編集

Debian系

Debian

これはUbutnuを使用する前後とラズベリーパイ(Raspbian)で使っていたのですが、GNUの精神の完全自由を目指すコミュニティベースのディストロです。

昔からあるディストリビューションですので、情報はかなり豊富です。パッケージリポジトリにあるパッケージ(aptなどでインストールできるソフトウェア)も豊富でわざわざビルドしなくて良いことが多いです。
ただし、自由の定義が他のディストロより厳格でオープンソースであってもDebian Projectが自由でないと判断したソフトはNon-Freeリポジトリに取り入れられる、名称が変わるなどされるため、混乱することがあるかもしれません。(FirefoxとIceweaselの関係がよく知られた例です。)デスクトップ環境環境はGNOME3やKDE Plasma Desktopなどおおよそのものは揃っています。
安定版のパッケージリポジトリから降ってくるソフトウェアのバージョンは古いです。バージョンが古いのが気になる方は、安定版ではなくtesting(次期リリース予定)か、”sid”と呼ばれる不安定版を利用されると良いと思います。この場合はバグに遭遇する可能性はありますが、testingはそんなに困る状況に陥ることは少ないと思います。パッケージメンテナーの方には日本人も多くいらっしゃり、OSCなどでお会いして話すこともあるため、そこで情報交換ができるかもしれません。

Ubuntu

Debianから派生した大規模なディストロです。Linux入門としてWindowsからの乗り換え先として有名で、以前はWindowsのサポートが切れると「Ubuntuへの乗り換える方法」なんて本が出ていました。

Unityというちょっと(名前と動作が)ややこしいUIを持っています。Windowsから来た人がこのUIに慣れるかでその後のLinux人生が決まる…かもしれませんGNOME3に移行しました。

ネットを漁れば情報は山ほど出てきます。初心者に優しく、GUIツールが充実しているのでCUIを知らなくてもなんとかなると思います。
パッケージのバージョンはそこそこ古いですが、Debianのsidと同じバージョンのパッケージが多いです。Debian同様安定性重視だと思われるので、問題が発生するのを極力避けたい場合には最適です。すぐに新しいパッケージが使いたい場合は開発版を使うか他のディストリビューションを利用しましょう。
デスクトップ環境はGNOME3以外にもLXDEやKDE Plasma Desktop、MATEなどをサポートしたフレーバーが存在しており、Kubuntuなどの名前がついています。
初心者の方にはおおよそおすすめできますが、チューニングが必要なPC・環境などでは別のディストリビューションを利用したほうが良いでしょう。

Linux Mint

Ubuntuに不満がある人が駆け込んでるイメージがあるディストリビューションです(個人の感想です)。上記2つのディストロより、非オープンソースに対して寛大で一部の音声コーディックなどが標準で入っています。標準デスクトップ環境のCinnamonは、GNOME3と違ってWindowsライクなUIで安心する人が多いようです。日本語環境も昔よりかなり充実しており、初心者の方も戸惑うことなく安心して使えると思います。GUIツールも豊富で大抵の設定はできると思います。おおよその知識はUbuntuやDebianの技術を流用できると思いますし、Linux Mint Japanのフォーラムもあるので、そこで質問しながら勉強していくと良いと思います。

Zorin OS

WindowsとそっくりのUIとMacとそっくりのUIを持つディストリビューションです。爽やかなUIが好感が持てます。ただし、有料版があるので、無料版に若干の機能制限がかかってます。日本語対応はバージョン9でかなり良くなりました。隠れたLinux入門の道と言うところでしょうか。
最近は使ってないのでもしかしたら変わっているかもしれませんが、Wine(Windowsアプリケーションを動かすためのライブラリ群)の調整がうまく行っており、3Dゲームも一発で動くことが多いです。

Red Hat系

CentOS

CentOS 8まではRHEL(有料)のソースコードから商標や商用パッケージが削除されたものを使用しているディストリビューションです(クローンではなく、CentOS独自の変更も存在します)。サーバー用途で使用されることが多く感じますがデスクトップ環境も利用できます。Linuxでサーバを構築したい場合には、サーバ関係の情報がネットに落ちているこのディストリビューションがやりやすいのではないでしょうか。
前述のディストリビューション同様安定重視ですが、バージョンはそれほど古くなく各アプリケーションのメインバージョンに近いものが降ってきます。
個人的な感想ではデスクトップ利用者はこちらより後述のFedoraの方が人気である感じがします。一方で大学などのラボではこれが使われている所を見ます。
2020年に方針転換があり、CentOSはCentOS StreamとなりFedoraとRHELの中間に位置する扱いになりました。サーバ用途では長期間の安定性を求める場合は別のディストリビューションに移行する必要があるかもしれません。

Fedora

かつて存在していたRed Hat Linux(現在はRHEL)の後継のような存在です。Red Hat社の支援を受けたコミュニティが開発しており、かなり活発に開発されています。パッケージ管理システムもDebian系列のdpkgと違いRPMを用いています。個人的にはUbuntuとFedoraがLinuxディストリビューションの双璧を成している感じがします。6ヶ月ごとにメジャーアップデートが行われ、パッケージのバージョンも新しいのが多いです。ここで変更によって得られた改善などがRHELに還元されることもあります。仕様変更も発生し、最近ではパッケージマネージャーがyumからDNFに変更されました。昔使っていたときより安定性が高くなってると聞きますが最近使ってないのでわかりません。昔自分が使っていた時、パッケージ依存関係がぶっ壊れたり起動しなくなったりと苦い思い出があるディストリビューションですが、パッケージマネージャも置き換えられましたし、ユーザも増えたので現在はかなり良くなっていると思います。通常のリリースに対してRawhideという不安定版があります。ただしこれは名前の通り結構な不安定で仮想マシンで動かしていたときは不具合が発生することもありました。Linuxの最新が知りたいという人には良いディストロだと思いますし、ある程度の知識が身についた後に長く愛用するディストリビューションとしては最適かもしれません。

Vine Linux

国産のディストリビューションであり、これが好感されることも多いです。フォーラムでも気軽に日本語で質問できますし、日本語環境はしっかり整っています。ただし、すべてのエラーメッセージが日本語であることではなく、もちろん英語のエラーメッセージも存在します。パッケージマネージャはAPT-RPMというdpkgのフロントエンドとして用いられるAPTをFedoraで使われているRPMに移植したものを使っています。開発はかなりゆっくりでメジャーアップデートも多くないのですが、最近は特に開発が停滞しているような気がします。Firefoxのバージョンも古いのでセキュリティ的な不安は残ります。
かつては人に勧めていましたが、今は勧めづらいです。

Berry Linux

軽量なディストリビューションです。描画が綺麗で、起動時の猫の写真はかわいく映ります。あまりつかったことがないので詳しい事はわかりませんが、シンプルで良さそうです。

Slackware系

openSUSE

現在サーバで使用しているディストリビューションです。
公式リポから降ってくるソフトは少し古いですがDebianほどではありません。
日本ではシェアが少ないですが、海外では多いため有名なソフトではopenSUSEでのインストール方法が書かれています。SlackやChromeなどのrpmパッケージはおおよそ流用できますが、Fedoraなどとパッケージ命名が違うこともあるので依存パッケージが多いと依存関係を手動で解決する必要があります。
Arch Linuxと同じくローリングリリースのTumbleweedがあり、最新のパッケージが落ちてきます。最新と言っても不安定版が降ってくることはあまりないのでおおよそ安定して使うことができます。デスクトップ環境は初期インストールではGNOME3かKDE Plasma Desktopの二択ですが、あとで他のデスクトップ環境に切り替えられます。デスクトップではTumbleweedで新しいパッケージを、サーバーは安定したLeapを使い、openSUSEで固めることでディストロ間の設定の仕方の違いで悩むことをなくすこともできます。

Yastがコントロールパネルのように強くまとまっています。
弱点としては上記の通り日本でのシェアが低いため、情報が見つけにくい、Slackwareの血を引いているので設定が若干難しい、などが挙げられます。
時期によってはパッケージの更新が滞っていたり、削除される(nginx-modulesとandorid-toolsが消えたのは痛かったです)などがあり、自分でビルドすることも多々あります。特にVLCの公式ページに置かれているopenSUSE用のパッケージが長らく更新されない時期がありました。
日本のコミュニティもありOSCなどにも参加されているので連携しながら対応していくのも手かと思います。
2021/04現在このサーバーはopenSUSEで動いてますが、特に問題はないです。

Puppy Linux(Ver.5以前)

起動時にワンワンと大音量でなってびっくりした思い出があるディストリビューションです。バージョン5以降はいろいろあってubuntu系になったそうですが、使っていないのでここでは述べません。
メモリ128MBでも動く軽さです。XP時代のPCでもなんなく動かすことができ、CDから起動するときは起動時にファイルをRAMに転送するようなので起動後にCDを取り出しても作業を続行することができます。ただし、最新のデバイスには対応していないので、そのような状況下では正常動作しません。自分はデータ救出用として重宝しています。

独立系

Arch Linux

Linuxについて調べていると必ず遭遇するArch Wikiでよく知られているディストリビューションです。組み立て型OSというべきディストリビューションでデベロッパーフレンドリーを掲げています。インストールはGUIインストーラが存在せず、CUI環境下で行います。インストール作業はそこまで難解ではなくむしろ自由で、インストール時に特殊なドライバーを入れたい場合はとても柔軟に行えます。ローリングリリースモデルを採用しているのでメジャーアップデートがありません。GUIだけで全てが完結することはまずないと思いますので、コマンドあたりの知識は必須となります。公式リポジトリも最新版のパッケージが利用されています。一週間使用しないと1000件のアップデートが溜まっていることもしばしばあります。

デスクトップ環境もおおよそのものは用意されています。Xorg環境の整備に若干戸惑うことはあるかもしれませんが、良い勉強になるでしょう。AURという非公式のパッケージ群もありそこからChromeなども手に入ります。(余談ですが、知識が古いのでyaourtがなくなってyayが主流になっていたことを知らなかったです、と書いていたらyayも古くなったとか…)

デベロッパーフレンドリーを掲げているために細かい微調整が必要になる部分があるため、環境構築にはじっくり時間をかける必要がありますが、自分好みに調整しやすいでしょう。

Solus Linux

よくSolarisと聞き間違えられますが、「ソーラス」です。デスクトップ環境専用ディストリビューションとして開発されており、かなりすっきりにまとまっています。重複したパッケージを導入しないという目標を掲げているようですが、様々な選択肢があるのがLinuxエコシステムの特徴とも言えるので、これに関しては微妙な気持ちになっています。
日本で常用している人はほとんど見かけません(自分は現在メインで使っていますが)。パッケージ管理システムはeopkgという独自のシステムですが、GUIのパッケージマネージャーを使うことでChromeやSlackは導入できます。落ちてくるパッケージは概ね最新版で不満はない程度ですがopenSSLなど一部古いものもあります。Budgieというデスクトップ環境を開発しており、モダンなデザインで扱いやすいものになっています(Budgie自体は他のディストリビューションでも利用できます)。

ibus-mozcが公式リポジトリに存在しないため、スクリプトを書いてパッケージリクエストを行いましたが途中で返信がなくなっているためリポジトリには取り込まれていません。そのため日本語環境は整っているとは言い難いです。しかしながらGNOME3やKDE Plasma Desktop自体は日本語化は十分なされているので普段使いで困ることはないと思います。
追記(2020/10/25):mozcが追加されました。

(Pear OS)

今はなきディストリビューションで林檎じゃなくて梨です。要は林檎のそっくりデザインさんでして林檎社に食われて死んだという噂が流れています。軽くて快適でしたがアプリが案外少なかったと思います。ネットに情報が少なくどこの部類に入るか悩みますが、リポジトリがUbutnuのものだった気がするのでDebian系であると思います。消滅したディストリビューションですのでここでは一番下においてます。今でもインストールDVDは持っているのですが、UI部分のアップデートがなく不具合が起きそうなので使用しておりません。似たようなデザインのディストリビューションとして、elementary OSがあるので、使ってみてはいかがでしょうか。自分はelementary OSを使ったことがないのでここでは紹介しません。

まとめ

初心者におすすめしたいと思うのはLinux Mint、Ubuntuあたりです。
多くのOSでは安定志向が強いので古いパッケージが降ってきますが最初のうちはこだわらない限り気にならないでしょう。
紹介の中でパッケージが古いことを挙げていますが、安定して動くことを目的としており逆に最新パッケージを利用しているディストリビューションでは再起動すると起動してこなくなった…なんてこともありますので、利用者の方針に沿って利用してください。
なお、この記事は個人の意見なのであくまで参考程度で利用してください。
ほとんどのディストリビューションは無料ですので、慣れてきたら別のディストリビューションに挑戦するのも良いでしょう。

新サーバーとIPv6/IPv4ネットワーク構成とNginx暴走

この度引越しに伴い、実家で「引越し先で光回線使えるならこのクソデカサーバーとUPS持っていけ」と言われたのでサーバー機は高校同期に譲渡し(ついでにLinux沼に沈めて)、新しく作ることにしました。
念願のRyzenを使い、更にベアボーンキットを使って小型化しつつ、NVMeなSSD2つ使ってRAID1で組みました。
実家はBBIQだったのでIPv4環境だったわけですが、こちらではフレッツ光パワーでIPv6環境が手に入りました。
さてIPv6な環境が手に入った瞬間、「IPv4なんて知らねーウォォォォ」とIPv6以外でアクセスできないサーバを構築しそうになったわけですが、残念ながらそういうわけには行かないわけです。
別にIPv6でもPPPoEで通信すればグローバルなIPv6/IPv4アドレスが降ってくるわけですが、新しい物好きでネットは速いほうがいいのでIPoEで通信したくてIPv4 over IPv6してほしいわけです。この方式だとIPv6は半固定なグローバルIPアドレスが降ってくるのですが、IPv4の方はIPアドレスが共有されてしまい、ウェルノウンポートが使えなくなります。
CDNや中間サーバを挟んでポートフォワーディングしてやる方法も考えたのですが、スイッチングハブを間に挟みルータの外にサーバーを出してやることで解決しました。
この構成にするとサーバーでPPPoEを張らなければならず、rp-pppoeを導入しました。
pppoe-setupコマンドを叩いてIDとパスワードを入力し、ファイアーウォールはNONEを選択します。(後でfirewalldで設定します)
設定が終わると、/etc/sysconfig/network/ifcfg-ppp0 ができているはずなのでこれに
LINUX_PLUGIN=/usr/lib64/pppd/2.4.7/rp-pppoe.so
を追記します。
設定が終わった後に
sudo systemctl start pppoe
とでもしてあげれば接続が開始されppp0ができています。ファイアーウォールで適宜ポート開放して動くことが確認できたらenableで起動時に自動接続するようにします。
NginxやDovecotでppp0をlistenするようにしてDDNSにはIPv6アドレスとPPPで得られたIPv4アドレスを通知するようにします。

さて、このように設定してついでにマストドンのサーバも移行し「夜も遅いし、サーバー移動も終わったし、寝るかぁ」と最後にRyzenパワーを見ようとhtopを開いていくつかのページを閲覧したところ…

htopコマンドの様子

これを見て眠れるわけがない、顔面真っ青案件が広がってました。
最初はマストドンのSidekiqあたりが再試行で暴走しているのかと思って確認画面を見たが特に暴走している様子もなく、nginxが常に上に張り付きだし、そうこうしてたらswapperが出てきて忙しく動き出したので慌ててNginxを止めることになりました…。
NAXSIとマストドンの組み合わせが怪しいと考え、拡張機能をすべて切り離し、再現する条件を探していって結局、NAXSIではなくBrotliプラグインとproxy_passの組み合わせで再現することが判明しました。BrotliをOFFにして無事平穏を取り戻しました…
原因解明と行きたいですが、疲れたのでそれはまたの機会にします。

というわけでRyzen3 PROなCPUを搭載した新サーバーとIPv6環境でもアクセスできる新環境になりました。