태그 보관물: 유닉스계열

OpenBSD에 ZeroTier-One VPN 설치하기

이 글은 OpenBSD 7.2 버전과 ZeroTier One 1.10.6 버전을 사용합니다.
글 작성 시점에서 OS와 소프트웨어의 가장 최신 버전입니다.

OS 정보

$ uname -a

OpenBSD openbsd.ourdare.com 7.2 GENERIC.MP#758 amd64

필요한 패키지 설치

$ sudo pkg_add wget gmake

quirks-6.42 signed on 2023-03-21T19:29:38Z
wget-1.21.3:libunistring-0.9.7: ok
wget-1.21.3:libidn2-2.3.0p0: ok
wget-1.21.3:bzip2-1.0.8p0: ok
wget-1.21.3:pcre2-10.37: ok
wget-1.21.3:libpsl-0.21.1: ok
wget-1.21.3: ok
gmake-4.3: ok

ZeroTier-One 소스 다운로드 및 압축 해제

$ wget https://github.com/zerotier/ZeroTierOne/archive/refs/tags/1.10.6.tar.gz

--2023-03-29 14:05:54--  https://github.com/zerotier/ZeroTierOne/archive/refs/tags/1.10.6.tar.gz
github.com (github.com) 해석 중... 20.200.245.247
다음으로 연결 중: github.com (github.com)|20.200.245.247|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 302 Found
위치: https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/refs/tags/1.10.6 [따라감]
--2023-03-29 14:05:55--  https://codeload.github.com/zerotier/ZeroTierOne/tar.gz/refs/tags/1.10.6
codeload.github.com (codeload.github.com) 해석 중... 20.200.245.246
다음으로 연결 중: codeload.github.com (codeload.github.com)|20.200.245.246|:443... 연결했습니다.
HTTP 요청을 보냈습니다. 응답 기다리는 중... 200 OK
길이: 15259391 (15M) [application/x-gzip]
저장 위치: `1.10.6.tar.gz'

1.10.6.tar.gz	100%[======================================================================>]  14.55M  6.90MB/s    /  2.1s

2023-03-29 14:05:57 (6.90 MB/s) - `1.10.6.tar.gz' 저장함 [15259391/15259391]



$ tar xzf 1.10.6.tar.gz

빌드 및 설치

$ cd ZeroTierOne-1.10.6



$ gmake && sudo gmake install

서비스 등록 및 시작

/etc/rc.d/zerotier 를 새로 만들어서 아래 내용으로 채우고 저장합니다.

#!/bin/ksh

daemon="/usr/local/sbin/zerotier-one -d"

. /etc/rc.d/rc.subr

rc_cmd $1
$ sudo chmod u+x /etc/rc.d/zerotier



$ sudo rcctl enable zerotier



$ sudo rcctl start zerotier

zerotier(ok)

명령어 사용

$ sudo zerotier-cli info
200 info ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ 1.10.6 ONLINE



$ sudo zerotier-cli join <networkid>

OmniOS에서 OpenTTD JGRPP Dedicated 서버 구축하기 (Unix / Oracle Solaris / illumos)

※ 이 글에서는 OmniOS r151038 버전과 JGRPP v0.52.0 버전이 사용되었습니다.
글 작성 시점에서 r151038 버전은 OmniOS LTS 릴리즈의 가장 최신 버전이고, v0.52.0은 JGRPP의 가장 최신 릴리즈입니다.

OS 정보

~$ uname -a



SunOS omnioslts 5.11 omnios-r151038-7bb369b3b5 i86pc i386 i86pc



~$ cat /etc/os-release



NAME="OmniOS"
PRETTY_NAME="OmniOS Community Edition v11 r151038cs"
CPE_NAME="cpe:/o:omniosce:omnios:11:151038:97"
ID=omnios
VERSION=r151038cs
VERSION_ID=r151038cs
BUILD_ID=151038.97.2023.03.11
HOME_URL="https://omnios.org/"
SUPPORT_URL="https://omnios.org/"
BUG_REPORT_URL="https://github.com/omniosorg/omnios-build/issues/new"

필요한 패키지 설치

~$ sudo pkg install gcc10 cmake gnu-make



설치할 패키지:   2
변경할 서비스:   1
부트 환경 만들기: 아니오
백업 부트 환경 만들기: 아니오

다운로드		패키지	파일		XFER(MB)		속도
완료됨		2/2	3199/3199	25.5/25.5		471k/s

단계					항목
작업 설치				3358/3358
패키지 상태 데이터베이스 업데이트		완료
패키지 캐시 업데이트			0/0
이미지 상태 업데이트			완료
빠른 조회 데이터베이스 만들기		완료
검색 색인 읽기				완료
검색 색인 업데이트			2/2
패키지 캐시 업데이트			2/2



~$ gcc --version



gcc (OmniOS 151038/10.4.0-il-1) 10.4.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



~$ cmake --version



cmake version 3.25.3

CMake suite maintained and supported by Kitware (kitware.com/cmake).



~$ gmake --version



GNU Make 4.3
Built for x86_64-pc-solaris2.11
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

JGRPP 소스 다운로드 및 압축 해제

~$ wget https://github.com/JGRennison/OpenTTD-patches/archive/refs/tags/jgrpp-0.52.0.tar.gz



--2023-03-24 15:02:55--  https://github.com/JGRennison/OpenTTD-patches/archive/refs/tags/jgrpp-0.52.0.tar.gz
Resolving github.com... 20.200.245.247
Connecting to github.com|20.200.245.247|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/JGRennison/OpenTTD-patches/tar.gz/refs/tags/jgrpp-0.52.0 [following]
--2023-03-24 15:02:56--  https://codeload.github.com/JGRennison/OpenTTD-patches/tar.gz/refs/tags/jgrpp-0.52.0
Resolving codeload.github.com... 20.200.245.246
Connecting to codeload.github.com|20.200.245.246|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: ‘jgrpp-0.52.0.tar.gz’

jgrpp-0.52.0.tar.gz                      [          <=>                                                         ]  11.64M  6.13MB/s    in 1.9s

2023-03-24 15:02:58 (6.13 MB/s) - ‘jgrpp-0.52.0.tar.gz’ saved [12207921]



~$ tar xzf jgrpp-0.52.0.tar.gz

소스 파일 수정

압축을 풀어서 나온 소스 폴더로 이동.

~$ cd OpenTTD-patches-jgrpp-0.52.0

CMakeLists.txt 를 텍스트 편집기로 열어 313 줄에 위치한 target_link_libraries 함수 내부에 아래 세 줄을 추가.

${CMAKE_DL_LIBS}
-lsocket
-lnsl


add_dependencies(openttd
    find_version)

target_link_libraries(openttd
    openttd::languages
    openttd::settings
    openttd::media
    openttd::basesets
    openttd::script_api
    openttd::binfiles
    Threads::Threads
    ${CMAKE_DL_LIBS}
    -lsocket
    -lnsl
)

if(HAIKU)
    target_link_libraries(openttd "be" "network" "midi")
endif()

build-dedicated.sh 를 텍스트 편집기로 열어 7 줄 중간에 위치한 make를 gmake로 변경.


cd build
rm CMakeCache.txt
cmake .. -DOPTION_DEDICATED=true && gmake -j$(nproc 2>/dev/null || echo "1")

src/core/alloc_func.hpp 를 텍스트 편집기로 열어 맨 위에 아래 세 줄을 추가.

#ifdef __sun
#include <alloca.h>
#endif
#ifdef __sun
#include <alloca.h>
#endif

/*
 * This file is part of OpenTTD.

src/string_func.h 를 텍스트 편집기로 열어 279 줄 앞에 // 를 추가해 주석 처리.



#       define DEFINE_STRCASESTR
// char *strcasestr(const char *haystack, const char *needle);
#endif /* strcasestr is available */

src/network/core/os_abstraction.cpp 를 텍스트 편집기로 열어 196 줄 중간의 SO_REUSEPORTSO_REUSEADDR 로 변경.



#else
        int reuse_port = 1;
        return setsockopt(d, SOL_SOCKET, SO_REUSEADDR, &reuse_port, sizeof(reuse_port)) == 0;
#endif
}

src/3rdparty/randombytes/randombytes.h 를 텍스트 편집기로 열어 19 줄의 randombytes 함수를 아래와 같이 수정.



/*
 * Write `n` bytes of high quality random bytes to `buf`
 */
int randombytes(unsigned char *buf, size_t n);

#ifdef __cplusplus
}
#endif

src/3rdparty/randombytes/randombytes.c 를 텍스트 편집기로 열어 내용을 모두 삭제한 뒤 아래 내용으로 채우기.

#include "randombytes.h"
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

int randombytes(unsigned char *x, size_t xlen)
{
    int fd;
    ssize_t bytes_read;

    if (xlen == 0) return 0;
    assert(x != NULL);

    fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1) {
        fd = open("/dev/random", O_RDONLY);
    }
    assert(fd != -1);

    bytes_read = read(fd, x, xlen);
    assert(bytes_read == xlen);

    close(fd);

    return 0;
}

src/os/unix/crashlog_unix.cpp 를 텍스트 편집기로 열어 #include <ucontext.h> 한 줄을 25 줄에 위치한 #include <sys/mman.h> 아래에 추가.


#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <ucontext.h>

#if defined(WITH_DBG_GDB)
#include <sys/syscall.h>
#endif /* WITH_DBG_GDB */

같은 파일에서 400, 418 줄에 위치한 gregs[REG_EFL] 두 개를 gregs[REG_RFL] 로 변경.


                        gregs[REG_R14],
                        gregs[REG_R15],
                        gregs[REG_RIP],
                        gregs[REG_RFL]
                );
#elif defined(__i386)
                const gregset_t &gregs = ucontext->uc_mcontext.gregs;
                buffer += seprintf(buffer, last,

                        gregs[REG_EBP],
                        gregs[REG_ESP],
                        gregs[REG_EIP],
                        gregs[REG_RFL]
                );
#endif
#endif

빌드

~$ ./build-dedicated.sh

Base Graphics 다운로드 및 압축 해제

~$ wget https://cdn.openttd.org/opengfx-releases/7.1/opengfx-7.1-all.zip



Resolving cdn.openttd.org... 54.230.167.118, 54.230.167.93, 54.230.167.82, ...
Connecting to cdn.openttd.org|54.230.167.118|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3547160 (3.4M) [application/zip]
Saving to: ‘opengfx-7.1-all.zip’

opengfx-7.1-all.zip                  100%[=====================================================================>]   3.38M  9.53MB/s    in 0.4s

2023-03-24 16:02:24 (9.53 MB/s) - ‘opengfx-7.1-all.zip’ saved [3547160/3547160]



~$ unzip opengfx-7.1-all.zip && mv opengfx-7.1.tar build/baseset/



Archive:  opengfx-7.1-all.zip
  inflating: opengfx-7.1.tar

설치

~$ cd build && sudo gmake install

서버 실행

~$ /usr/local/games/openttd -D

OmniOS에서 마인크래프트 서버 구축하기 (Paper Spigot 1.17 +) (Unix / Oracle Solaris / illumos)

OS 정보

~$ uname -a

SunOS minecraft 5.11 omnios-master-72433da6283 i86pc i386 i86pc

~$ cat /etc/os-release

NAME="OmniOS"
PRETTY_NAME="OmniOS Community Edition v11 r151041"
CPE_NAME="cpe:/o:omniosce:omnios:11:151041:0"
ID=omnios
VERSION=r151041
VERSION_ID=r151041
BUILD_ID=151041.0.2021.11.19
HOME_URL="https://omnios.org/"
SUPPORT_URL="https://omnios.org/"
BUG_REPORT_URL="https://github.com/omniosorg/omnios-build/issues/new"

Java 확인 및 설치

~$ java

-bash: java: command not found

~$ pkg search jdk | awk '/17/'

basename    dir    usr/jdk                   pkg:/runtime/java/openjdk17@17.0.1.12-151041.0
basename    dir    usr/jdk                   pkg:/runtime/java/openjdk17@17.0.1.12-151041.0

~$ sudo pkg install openjdk17

     설치할 패키지:   2
     변경할 조정자:   1
     변경할 서비스:   1
   부트 환경 만들기: 아니오
백업 부트 환경 만들기: 아니오

다운로드                                     패키지            파일     XFER(MB)      속도
완료됨                                      2/2       250/250  139.1/139.1  1.4M/s

단계                                                항목
새 작업 설치                                      624/624
패키지 상태 데이터베이스 업데이트                                완료 
패키지 캐시 업데이트                                      0/0 
이미지 상태 업데이트                                       완료 
빠른 조회 데이터베이스 만들기                                  완료 
검색 색인 읽기                                          완료 
검색 색인 업데이트                                       2/2 
패키지 캐시 업데이트                                      2/2 

~$ java -version

openjdk version "17.0.1" 2021-10-19
OpenJDK Runtime Environment (build 17.0.1+12-omnios-151041)
OpenJDK 64-Bit Server VM (build 17.0.1+12-omnios-151041, mixed mode, sharing)

마인크래프트 디렉터리 생성, Paper Spigot 다운로드 및 실행

~$ mkdir ~/minecraft && cd ~/minecraft

https://papermc.io/downloads 에서 최신버전의 Paper Spigot 다운로드

~/minecraft$ wget https://papermc.io/api/v2/projects/paper/versions/1.17.1/builds/388/downloads/paper-1.17.1-388.jar

--2021-11-26 11:20:47--  https://papermc.io/api/v2/projects/paper/versions/1.17.1/builds/388/downloads/paper-1.17.1-388.jar
Resolving papermc.io... 172.67.72.198, 104.26.13.138, 104.26.12.138, ...
Connecting to papermc.io|172.67.72.198|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 61843877 (59M) [application/java-archive]
Saving to: ‘paper-1.17.1-388.jar’

paper-1.17.1-388.jar                                                                100%[================================================================================================================================================================================================================>]  58.98M  66.0MB/s    in 0.9s    

2021-11-26 11:20:48 (66.0 MB/s) - ‘paper-1.17.1-388.jar’ saved [61843877/61843877]

~/minecraft$ java -Xms14G -Xmx15G -jar paper-1.17.1-388.jar 

Downloading vanilla jar...
Patching vanilla jar...
System Info: Java 17 (OpenJDK 64-Bit Server VM 17.0.1+12-omnios-151041) Host: SunOS 5.11 (amd64)
Loading libraries, please wait...
[11:32:27 ERROR]: Failed to load properties from file: server.properties
[11:32:27 WARN]: Failed to load eula.txt
[11:32:27 INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

~/minecraft/eula.txt 의 eula=false 부분을 eula=true 로 수정

~/minecraft$ java -Xms14G -Xmx15G -jar paper-1.17.1-388.jar

System Info: Java 17 (OpenJDK 64-Bit Server VM 17.0.1+12-omnios-151041) Host: SunOS 5.11 (amd64)
Loading libraries, please wait...
[11:33:17 INFO]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD'
[11:33:17 INFO]: Found new data pack file/bukkit, loading it automatically
[11:33:18 INFO]: Reloading ResourceManager: Default, bukkit
[11:33:18 INFO]: Loaded 7 recipes
[11:33:19 INFO]: Starting minecraft server version 1.17.1
[11:33:19 INFO]: Loading properties
[11:33:19 INFO]: This server is running Paper version git-Paper-388 (MC: 1.17.1) (Implementing API version 1.17.1-R0.1-SNAPSHOT) (Git: 22aaf91)
[11:33:19 INFO]: Server Ping Player Sample Count: 12
[11:33:19 INFO]: Using 4 threads for Netty based IO
[11:33:19 INFO]: Default game type: SURVIVAL
[11:33:19 INFO]: Generating keypair
[11:33:19 INFO]: Starting Minecraft server on *:25565
[11:33:19 INFO]: Using default channel type
[11:33:19 INFO]: Paper: Using Java 11 compression from Velocity.
[11:33:19 INFO]: Paper: Using Java cipher from Velocity.
[11:33:20 INFO]: Preparing level "world"
[11:33:22 WARN]: Unable to find spawn biome
[11:33:23 WARN]: Unable to find spawn biome
[11:33:23 INFO]: Preparing start region for dimension minecraft:overworld
[11:33:23 INFO]: Preparing spawn area: 0%
[11:33:23 INFO]: Time elapsed: 289 ms
[11:33:23 INFO]: Preparing start region for dimension minecraft:the_nether
[11:33:23 INFO]: Time elapsed: 170 ms
[11:33:23 INFO]: Preparing start region for dimension minecraft:the_end
[11:33:23 INFO]: Time elapsed: 69 ms
[11:33:23 INFO]: Running delayed init tasks
[11:33:23 INFO]: Done (4.384s)! For help, type "help"
[11:33:23 INFO]: Timings Reset
> 

※ 실행 명령어의 -Xms14G/-Xmx15G 부분을 서버 환경에 맞게 수정하여 할당할 최소 메모리와 최대 메모리 설정

OmniOS에서 마인크래프트 서버 구축하기 (Paper Spigot ~1.16.x) (Unix / Oracle Solaris / illumos)

※ 마인크래프트 1.17 버전 이후는 최신 글을 확인하세요.

OS 정보

~$ uname -a

SunOS omni 5.11 omnios-master-b7ba24aaa1 i86pc i386 i86pc

~$ cat /etc/os-release

NAME="OmniOS"
PRETTY_NAME="OmniOS Community Edition v11 r151035"
CPE_NAME="cpe:/o:omniosce:omnios:11:151035:0"
ID=omnios
VERSION=r151035
VERSION_ID=r151035
BUILD_ID=151035.0.2020.09.26

Java 확인 및 설치

~$ java -version

-bash: java: command not found

~$ sudo pkg install jdk

Packages to install: 2 Mediators to change: 1 Services to change: 1 Create boot environment: No
Create backup boot environment: No
DOWNLOAD PKGS FILES XFER (MB) SPEED
Completed 2/2 371/371 101.1/101.1 1.0M/s
PHASE ITEMS
Installing new actions 537/537
Updating package state database Done
Updating package cache 0/0
Updating image state Done
Creating fast lookup database Done
Reading search index Done
Updating search index 2/2
Updating package cache 2/2

~$ java -version

openjdk version "1.8.0_265"
OpenJDK Runtime Environment (build 1.8.0_265-omnios-151035-b01)
OpenJDK 64-Bit Server VM (build 25.265-b01, mixed mode)

마인크래프트 디렉터리 생성 및 실행

~$ mkdir ~/minecraft && cd ~/minecraft

https://papermc.io/downloads 에서 다운로드 받은 서버 파일을 ~/minecraft 디렉터리로 이동

~/minecraft$ java -Xmx1G -jar paper-209.jar

Downloading vanilla jar…
Failed to download vanilla jar
javax.net.ssl.SSLException: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.ssl.Alerts.getSSLException(Alerts.java:214)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1967)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1924)
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1907)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1423)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1400)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1570)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
at java.net.URL.openStream(URL.java:1068)
at io.papermc.paperclip.Paperclip.checkVanillaJar(Paperclip.java:190)
at io.papermc.paperclip.Paperclip.checkPaperJar(Paperclip.java:121)
at io.papermc.paperclip.Paperclip.setupEnv(Paperclip.java:94)
at io.papermc.paperclip.Paperclip.main(Paperclip.java:48)
Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at sun.security.validator.PKIXValidator.(PKIXValidator.java:104)
at sun.security.validator.Validator.getInstance(Validator.java:181)
at sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:318)
at sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:179)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:193)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1670)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:226)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1082)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:1010)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1079)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1388)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1416)
… 11 more
Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
at java.security.cert.PKIXParameters.(PKIXParameters.java:120)
at java.security.cert.PKIXBuilderParameters.(PKIXBuilderParameters.java:104)
at sun.security.validator.PKIXValidator.(PKIXValidator.java:102)
… 23 more

https://www.oracle.com/kr/java/technologies/javase/javase-jdk8-downloads.html 에서

jdk-8u261-solaris-x64.tar.gz 파일 다운로드 및 압축 풀기

서버 /etc/ssl/java/cacerts 파일을 압축 풀어서 나온 /jdk-8u261-solaris-x64/jdk1.8.0_261/jre/lib/security/cacerts 파일로 대체

~/minecraft$ java -Xmx1G -jar paper-209.jar

Downloading vanilla jar…
Patching vanilla jar…
System Info: Java 1.8 (OpenJDK 64-Bit Server VM 25.265-b01) Host: SunOS 5.11 (amd64)
Loading libraries, please wait…
[16:23:35 ERROR]: Failed to load properties from file: server.properties
[16:23:35 WARN]: Failed to load eula.txt
[16:23:36 INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

~/minecraft/eula.txt 의 eula=false 부분을 eula=true 로 수정

~/minecraft$ java -Xmx1G -jar paper-209.jar

※ – 실행 명령어의 -Xmx1G부분에서 할당할 메모리 변경
4GB의 경우 -Xmx4G, 16GB의 경우 -Xmx16G