워드프레스를 플러그인 없이 쓰기 - SEO 플러그인이 정말 필요한가
워드프레스를 새로 세우면서 플러그인을 하나도 깔지 않기로 했습니다.
"그래도 SEO 플러그인은 있어야지" 싶었는데, 하나씩 따져보니 필요 없었습니다.
결론부터
| 보통 플러그인을 쓰는 기능 | 실제로는 |
|---|---|
| 사이트맵 생성 | 워드프레스 기본 제공 (/wp-sitemap.xml) |
| 메타 description · OG 태그 | 테마 코드 30줄 |
| 정규 주소(canonical) | 워드프레스 기본. 직접 넣으면 중복 |
| 캐시 | 트래픽 적으면 불필요 |
| 댓글 스팸 방지 | 댓글을 끄면 불필요 |
| 백업 | 서버에서 스크립트로 |
플러그인 0개로 돌아갑니다.
왜 줄이려 했나
플러그인은 남이 쓴 코드가 내 사이트에서 관리자 권한으로 도는 것입니다.
- 취약점이 생기면 그대로 공격 경로가 됩니다
- 개발자가 손을 놓으면 보안 패치가 멈춥니다
- 사이트가 느려지는 흔한 원인이기도 합니다
워드프레스 침해는 코어보다 플러그인·테마 취약점을 통하는 경우가 많다고 알려져 있습니다. 코어는 보안팀이 관리하고 패치도 빠르지만, 플러그인은 방치되면 그대로 남습니다.
안 쓰는 게 가장 안전합니다.
1. 사이트맵은 이미 있습니다
워드프레스 5.5부터 사이트맵이 기본 기능입니다.
curl -s https://example.com/wp-sitemap.xml | head -5
글·페이지·카테고리별로 나뉘어 나옵니다.
<sitemapindex>
<sitemap><loc>.../wp-sitemap-posts-post-1.xml</loc></sitemap>
<sitemap><loc>.../wp-sitemap-posts-page-1.xml</loc></sitemap>
<sitemap><loc>.../wp-sitemap-taxonomies-category-1.xml</loc></sitemap>
</sitemapindex>
SEO 플러그인을 사이트맵 때문에 깔 이유는 없습니다.
2. 메타 태그는 테마에 넣습니다
플러그인이 해주는 일 중 실제로 필요한 건 메타 description과 OG 태그입니다. 자식 테마의 functions.php 에 직접 넣으면 됩니다.
// 설명문: 발췌가 있으면 발췌, 없으면 본문 앞부분 155자
function mytheme_description() {
if (is_singular()) {
$post = get_queried_object();
$desc = has_excerpt($post) ? get_the_excerpt($post) : wp_strip_all_tags($post->post_content);
$desc = trim(preg_replace('/\s+/u', ' ', $desc));
return mb_substr($desc, 0, 155);
}
return get_bloginfo('description');
}
add_action('wp_head', function () {
$desc = esc_attr(mytheme_description());
$title = is_singular() ? get_the_title() : get_bloginfo('name');
$url = is_singular() ? get_permalink() : home_url('/');
echo '<meta name="description" content="' . $desc . '">' . "\n";
echo '<meta property="og:type" content="' . (is_singular() ? 'article' : 'website') . '">' . "\n";
echo '<meta property="og:title" content="' . esc_attr($title) . '">' . "\n";
echo '<meta property="og:description" content="' . $desc . '">' . "\n";
echo '<meta property="og:url" content="' . esc_url($url) . '">' . "\n";
echo '<meta name="twitter:card" content="summary_large_image">' . "\n";
if (is_singular() && has_post_thumbnail()) {
echo '<meta property="og:image" content="' . esc_url(get_the_post_thumbnail_url(null, 'large')) . '">' . "\n";
}
}, 1);
확인은 curl 로 합니다.
curl -s https://example.com/글주소/ | grep -E 'name="description"|og:'
⚠️ canonical은 넣지 마세요
처음에 정규 주소도 직접 넣었다가 중복 출력됐습니다.
<link rel="canonical" href="..." > ← 내가 넣은 것
<link rel="canonical" href="..." /> ← 워드프레스 기본
워드프레스가 이미 출력합니다. 직접 넣으면 두 개가 되어 오히려 해롭습니다.
curl -s https://example.com/글주소/ | grep -c 'rel="canonical"'
# 1 이어야 정상
처음엔 "플러그인이 해주는 건 다 직접 넣자"는 생각이었습니다. 그러다 보니 이미 있는 것까지 넣었습니다.
플러그인을 줄이려다 오히려 중복을 만든 셈입니다. 빼기 전에 기본으로 뭐가 제공되는지부터 확인하는 게 순서였습니다.
3. 덤으로 — 안 쓰는 출력 끄기
같은 자리에서 불필요한 기본 출력도 제거했습니다.
remove_action('wp_head', 'wp_generator'); // 워드프레스 버전 노출
remove_action('wp_head', 'wlwmanifest_link'); // Windows Live Writer (레거시)
remove_action('wp_head', 'rsd_link'); // Really Simple Discovery
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');
add_filter('xmlrpc_enabled', '__return_false'); // XML-RPC 차단
wp_generator 는 특히 꺼두는 게 좋습니다. 워드프레스 버전을 HTML에 그대로 적어주는데, 공격자가 취약 버전을 찾는 데 쓰입니다.
<meta name="generator" content="WordPress 7.1.2" /> ← 이게 나갑니다
XML-RPC 는 외부 앱에서 글을 쓰는 통로인데, 무차별 대입 공격의 흔한 경로입니다. 앱으로 글을 쓰지 않으면 닫는 게 낫습니다.
확인:
curl -s https://example.com/ | grep -cE 'name="generator"|wlwmanifest|emoji'
# 0 이면 제거됨
그래도 플러그인이 필요한 경우
무조건 안 쓰는 게 답은 아닙니다. 이런 건 직접 만들기 어렵습니다.
- 캐시 — 트래픽이 늘면 필요합니다
- 폼 — 문의 양식을 직접 만들면 스팸 처리까지 해야 합니다
- 보안 모니터링 — 로그인 시도 제한, 파일 변조 감지
- 이커머스 — 직접 만들 영역이 아닙니다
원칙은 "없어도 되면 안 쓴다" 입니다. 깔았다가 안 쓰게 된 것은 비활성화가 아니라 삭제합니다. 비활성 상태여도 파일은 서버에 남아 있고, 취약점은 그 파일을 통해 공격받습니다.
정리
- 사이트맵은 워드프레스 기본 기능입니다. 그것 때문에 플러그인을 깔지 마세요
- 메타 description·OG 태그는 테마 코드 30줄이면 됩니다
- canonical은 직접 넣지 마세요. 기본으로 나오고, 넣으면 중복됩니다
wp_generator와 XML-RPC는 끄는 게 좋습니다- 안 쓰는 플러그인은 비활성화가 아니라 삭제합니다