Beberapa hari ini salah satu script PHP yang saya gunakan error, setelah pindah server. Scriptnya seperti dibawah ini

<?php
$url = file_get_contents("https://xxx-prod.domain.com");
var_dump($url);

output dari script diatas

PHP Warning:  file_get_contents(): Peer certificate CN=`xxx-prod-v1.domain.com' did not match expected CN=`xxx-prod.domain.com' in /home/tommy/getIp.php on line 3
PHP Warning:  file_get_contents(): Failed to enable crypto in /home/tommy/getIp.php on line 3
PHP Warning:  file_get_contents(https://xxx-prod.domain.com): Failed to open stream: operation failed in /home/tommy/getIp.php on line 3
bool(false)

Error tersebut menyatakan bahwa SSL Common Name (CN) tidak sesuai dengan nama domain yang sedang saya akses, biasanya hal ini terjadi bisa di server salah setting untuk SSL yang digunakan. Saya coba buka dari beberapa browser, tidak ada masalah dan semuanya menampilkan SSL yang cocok.

Cek dengan curl dari server, hasilnya sama, jadi ini bukan masalah di PHP

curl: (60) SSL: no alternative certificate subject name matches target host name 'xxx-prod.domain.com'
More details here: https://curl.haxx.se/docs/sslcerts.html
 
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Coba telusuri lebih lanjut dengan ping

$ ping xxx-prod.domain.com
PING xxx-prod.domain.com(XXXX:XXXX:c0c:20ff::1 (XXXX:XXXX:c0c:20ff::1)) 56 data bytes
64 bytes from XXXX:XXXX:c0c:20ff::1 (XXXX:XXXX:c0c:20ff::1): icmp_seq=1 ttl=64 time=0.092 ms
64 bytes from XXXX:XXXX:c0c:20ff::1 (XXXX:XXXX:c0c:20ff::1): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from XXXX:XXXX:c0c:20ff::1 (XXXX:XXXX:c0c:20ff::1): icmp_seq=3 ttl=64 time=0.099 ms

dengan curl juga bisa dicek, dengan curl namadomain -k -v, hasilnya harusnya sama. Dengan hasil ping tersebut bisa di pastikan bahwa server tersebut salah mengkonfigurasi SSL untuk IPv6-nya, jadi yang valid hanya untuk IPv4, karena dari komputer saya yang tidak ada IPv6 tidak ada masalah.

Karena sudah menemukan masalahnya, jadi kita buatkan solusinya, masalah ini bisa di atasi dari dua sisi, baik dari client ataupun server.

1. Dari Client

Bila domain tersebut punya orang lain, dan kita tidak punya akses ke servernya, maka dari script PHP yang sudah dibuat sebelumnya, kita tambahkan parameter untuk memaksa PHP menggunakan IPv4, karena tidak ada masalah disitu, jadi scriptnya berubah menjadi

<?php
$url = file_get_contents("https://xxx-prod.domain.com", false, stream_context_create(['socket' => ['bindto' => '0:0']]));
var_dump($url);

0:0 pada nilai diatas adalah IPv4, untuk IPv6 gunakan [::]:0

2. Dari Server

Bila server/domain tersebut anda yang mengelolanya, bisa di fix dengan menggunakan certificate yang benar untuk domain tersebut, contoh untuk Nginx ubah pada bagian

ssl_certificate /root/.acme.sh/xxx-prod.domain.com/fullchain.cer;
ssl_certificate_key /root/.acme.sh/xxx-prod.domain.com/xxx-prod.domain.com.key;

jangan lupa restart service nginx setelah melakukan perubahan.

Leave a comment

Your email address will not be published. Required fields are marked *