├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── README.md ├── instances.cc ├── instances.h ├── libmain.c ├── list.cpp └── prebuilt ├── libnss_ec2.so └── list /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | vc12 3 | 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "aws-sdk-cpp"] 2 | path = aws-sdk-cpp 3 | url = https://github.com/wates/aws-sdk-cpp.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(libnss_aws) 4 | 5 | 6 | if(CMAKE_COMPILER_IS_GNUCC) 7 | set(CMAKE_C_FLAGS "-fPIC -fno-strict-aliasing -O2")# --input-charset=utf8 --exec-charset=utf8 8 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 ${CMAKE_CXX_FLAGS}") 9 | add_definitions(-DGCC) 10 | elseif(MSVC) 11 | set(CMAKE_C_FLAGS "/W4 /wd4819 /wd4100") 12 | set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} /EHsc") 13 | add_definitions(-DWINDOWS) 14 | add_definitions(-D_WINDOWS) 15 | add_definitions(-D_CRT_SECURE_NO_WARNINGS) 16 | else() 17 | endif() 18 | 19 | add_subdirectory(aws-sdk-cpp) 20 | 21 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}/aws-sdk-cpp/aws-cpp-sdk-core/include 22 | ${CMAKE_CURRENT_SOURCE_DIR}/aws-sdk-cpp/aws-cpp-sdk-ec2/include 23 | ) 24 | 25 | 26 | add_executable(list list.cpp instances.cc) 27 | target_link_libraries(list aws-cpp-sdk-core aws-cpp-sdk-ec2) 28 | 29 | add_library(nss_ec2 SHARED libmain.c instances.cc) 30 | target_link_libraries(nss_ec2 aws-cpp-sdk-core aws-cpp-sdk-ec2) 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libnss_ec2 2 | ========== 3 | 4 | EC2 インスタンスの Name タグで Public IP Address を解決できるようになります。 5 | 6 | ssh や ping, telnet, mysql など名前解決を利用するアプリケーションで利用できます。 7 | 8 | ライブラリを組み込む前に、まずは同封の list コマンドで Public IP Address が出力されるか確認してみてください。 9 | 10 | Prebuilt 版のインストール方法(x86-64/ubuntu/trusty ~) 11 | ``` 12 | sudo cp prebuilt/libnss_ec2.so /lib/x86_64-linux-gnu/libnss_ec2.so.2 # .2 を忘れずに 13 | 14 | sudo vi /etc/nsswitch.conf 15 | 16 | hosts: files myhostname dns ec2 17 | # hosts: 行の dns より後ろに ec2 を追加する 18 | 19 | ``` 20 | 21 | 22 | ビルド方法 23 | ---------- 24 | 25 | CMake3 系や C++11 対応ビルド環境を必要に応じてインストールしてください。 26 | 27 | ``` 28 | git submodule update --init --recursive 29 | mkdir build 30 | cd build 31 | cmake .. 32 | make 33 | ``` 34 | 35 | -------------------------------------------------------------------------------- /instances.cc: -------------------------------------------------------------------------------- 1 | 2 | #include "instances.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namemap* ListInstances(int *len){ 23 | std::vector names; 24 | //const std::shared_ptr logr(new Aws::Utils::Logging::ConsoleLogSystem(Aws::Utils::Logging::LogLevel::Debug)); 25 | //Aws::Utils::Logging::InitializeAWSLogging(logr); 26 | Aws::Auth::DefaultAWSCredentialsProviderChain chain; 27 | Aws::Client::ClientConfiguration config; 28 | config.region = Aws::Region::AP_NORTHEAST_1; 29 | 30 | Aws::EC2::EC2Client ec2(chain.GetAWSCredentials(), config); 31 | Aws::EC2::Model::DescribeInstancesRequest req; 32 | Aws::EC2::Model::DescribeInstancesOutcome outcome = ec2.DescribeInstances(req); 33 | if (outcome.IsSuccess()){ 34 | Aws::EC2::Model::DescribeInstancesResponse res = outcome.GetResultWithOwnership(); 35 | for (auto reservation : res.GetReservations()){ 36 | for (auto instance : reservation.GetInstances()){ 37 | if (0 < instance.GetPublicIpAddress().size()){ 38 | for (auto tag : instance.GetTags()){ 39 | if (tag.GetKey() == "Name"){ 40 | namemap name; 41 | name.address = ntohl(inet_addr(instance.GetPublicIpAddress().c_str())); 42 | strcpy(name.name, tag.GetValue().c_str()); 43 | names.push_back(name); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | namemap *ret = new namemap[names.size()]; 52 | memcpy(ret, &*names.begin(), sizeof(namemap)*names.size()); 53 | *len = names.size(); 54 | return ret; 55 | } 56 | 57 | void FreeMap(namemap *p){ 58 | delete[]p; 59 | } 60 | 61 | unsigned int FindAddress(const char *name){ 62 | unsigned int addr = 0x00000000; 63 | int len = 0; 64 | namemap *names = ListInstances(&len); 65 | for (int i = 0; i < len; i++){ 66 | if (0 == strcmp(name, names[i].name)) 67 | addr = names[i].address; 68 | } 69 | FreeMap(names); 70 | return addr; 71 | } 72 | -------------------------------------------------------------------------------- /instances.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __cplusplus 3 | extern "C"{ 4 | #endif 5 | 6 | typedef struct namemap{ 7 | char name[256]; 8 | unsigned int address; 9 | }namemap_t; 10 | 11 | struct namemap* ListInstances(int *len); 12 | void FreeMap(struct namemap*); 13 | unsigned int FindAddress(const char *name); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /libmain.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "instances.h" 11 | 12 | static enum nss_status not_enough(int *errnop, int *h_errnop) 13 | { 14 | *errnop = ERANGE; 15 | *h_errnop = NETDB_INTERNAL; 16 | return NSS_STATUS_TRYAGAIN; 17 | } 18 | 19 | enum nss_status _nss_ec2_gethostbyname_r(const char *name, struct hostent *result_buf, char *buf, size_t _buflen, int *errnop, int *h_errnop) 20 | { 21 | char *p = buf; 22 | size_t len; 23 | uint32_t ip; 24 | ssize_t buflen = (ssize_t)_buflen; 25 | 26 | if (buflen == 0) return not_enough(errnop, h_errnop); 27 | 28 | ip = htonl(FindAddress(name)); 29 | if (ip == 0u) { 30 | *errnop = ENOENT; 31 | return NSS_STATUS_NOTFOUND; 32 | } 33 | 34 | // copy name 35 | len = snprintf(p, buflen, "%s", name); 36 | result_buf->h_name = p; 37 | p += len; 38 | buflen -= len; 39 | 40 | // alias (no set) 41 | if (buflen < (ssize_t)sizeof(char *)) return not_enough(errnop, h_errnop); 42 | 43 | ((char **)p)[0] = NULL; 44 | result_buf->h_aliases = (char **)p; 45 | p += sizeof(char *); 46 | buflen -= sizeof(char *); 47 | 48 | if (buflen == 0) return not_enough(errnop, h_errnop); 49 | 50 | // address type (2, AF_INET) 51 | result_buf->h_addrtype = AF_INET; 52 | 53 | // length (4, 32bit=IPv4 Address) 54 | result_buf->h_length = 4; 55 | 56 | // address 57 | if (buflen < (ssize_t)sizeof(char *) * 2) return not_enough(errnop, h_errnop); 58 | 59 | result_buf->h_addr_list = (char **)p; 60 | p += sizeof(char *) * 2; 61 | buflen -= sizeof(char *) * 2; 62 | 63 | if (buflen < 4) return not_enough(errnop, h_errnop); 64 | 65 | result_buf->h_addr_list[0] = p; 66 | memcpy(p, &ip, 4); 67 | p += 4; 68 | buflen -= 4; 69 | 70 | //if (buflen == 0) return not_enough(h_errnop); 71 | 72 | result_buf->h_addr_list[1] = NULL; 73 | 74 | return NSS_STATUS_SUCCESS; 75 | } 76 | 77 | 78 | enum nss_status 79 | _nss_ec2_gethostbyname2_r(const char *name, int af, struct hostent *result_buf, 80 | char *buf, size_t buflen, int *errnop, int *h_errnop) 81 | { 82 | if (af != AF_INET) return NSS_STATUS_NOTFOUND; 83 | return _nss_ec2_gethostbyname_r(name, result_buf, buf, buflen, errnop, h_errnop); 84 | } 85 | -------------------------------------------------------------------------------- /list.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "instances.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | int main(){ 10 | int len=0; 11 | namemap *names = ListInstances(&len); 12 | for (int i = 0; i < len; i++){ 13 | unsigned int hs = htonl(names[i].address); 14 | std::cout << inet_ntoa(*reinterpret_cast(&hs)) << " " << names[i].name << std::endl; 15 | } 16 | FreeMap(names); 17 | 18 | return 0; 19 | } -------------------------------------------------------------------------------- /prebuilt/libnss_ec2.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wates/libnss_ec2/47ff721d92ea1cc1a7ae912c36bf42cdfad5998d/prebuilt/libnss_ec2.so -------------------------------------------------------------------------------- /prebuilt/list: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wates/libnss_ec2/47ff721d92ea1cc1a7ae912c36bf42cdfad5998d/prebuilt/list --------------------------------------------------------------------------------