漢獻帝建安五年(公元200年)二月,袁紹任命沮授為監軍,統領10萬大軍,從邺城(今河南省安陽市北)出發,進攻許昌。袁紹則親率十餘萬冀州精兵到黃河北岸的黎陽(今河南省浚縣東北),建立自己的指揮部。他派大将郭圖和顔良進攻和黎陽隔岸相對的白馬(今河南省滑縣東)。袁紹企圖引誘曹操離開官渡(今河南中牟縣東北),然後一舉消滅曹軍。沮授向袁紹建議,顔将軍雖然勇猛,但驕傲自大,缺少智謀,不适合單獨統兵作戰。可袁紹固執己見,下令迅速渡河,打下白馬。
留守白馬的劉延聽說袁軍來進攻,急忙派人向曹操報告。而此刻,在許昌正展開一場是否抗袁的大辯論。名士孔融被袁紹的表面強大所迷惑,他認為:“袁紹轄地廣闊,擁兵數十萬,文有田豐、許攸這樣的謀上出謀,武有顔良、文醜這樣的勇将打仗,還有審配、逄紀這樣的忠臣效勞。與袁紹對抗,很難取勝。”許多人聽了,都情緒低落,隻有一個人挺身而出與孔融抗争,此人就是曹操的主要謀士荀彧。他說:“袁軍雖兵多,但法不嚴。而且田豐剛愎自用,無法與袁紹長期合作;許攸貪心太重,不能顧全大局;審配專斷,缺乏謀略;逄紀心兇狹小,又驕傲自大。這些謀士到一起怎麼能相容呢?至于顔良、文醜這類武将,皆有勇無謀,擒拿他們,對曹公來說,乃小事一樁。”荀彧這一番話,駁倒了孔融,也激勵了将士,增強了勝利的信心。曹操根據大家的建議,決定不和袁紹硬打硬拼,而采取聲東擊西、避實就虛的打法。曹操親率大軍西進延津(今河南省延津北),以誘惑袁軍主力西移,從而麻痹在白馬的顔良。果不出曹操所料,袁紹立即命令黎陽的守軍趕在曹軍渡河之前到達延津渡口,準備同曹軍決戰。曹軍見袁紹中計,就悄悄率領輕騎,急奔白馬。而此刻圍攻白馬的顔良正一心想困死白馬城内的軍民,他做夢也沒想到曹軍會在一夜之間趕回東邊,同自己決戰,所以毫無迎戰準備。在倉促應戰中,顔良被一匹火紅快馬上的将軍劈下馬。袁軍失去主将,頓時亂了陣腳。劉延也從城裡殺出,同曹操的兵馬兩面夾擊,一舉擊潰了顔良、郭圖的隊伍。而那位殺顔良的将軍,正是要報答曹操厚恩的關羽。
袁紹得知白馬戰敗,又失掉愛将,十分氣惱,緊急命令:全軍渡河,西追曹操。沮授急忙勸阻袁紹:“将軍,目前大軍應該屯在河北岸,隻派一路軍隊攻打河南岸的官渡。如果攻打下了官渡,我們就有了立足之地,然後大軍方可過河。否則貿然渡河,萬一有了意外,就可能全軍覆滅!”袁紹根本就聽不進勸阻,決意渡河。
袁軍渡過黃河,抵達延津後,袁紹派大将文醜追擊曹操。因為文醜和顔良是好朋友,為了立功和替顔良報仇,他快馬追擊。
一路上,到處都是曹軍丢下的車輛物資,山坡上有許多無主的戰馬,袁軍毫不懷疑這是曹軍倉促逃命時丢棄的。于是文醜的部下便争先恐後地跳下馬,一窩蜂地去搶奪戰利品。其實,他們中了曹操的計謀。此刻,曹操正在山頭觀望呢!一見文醜的隊伍亂了陣,一聲令下,曹兵就從四面八方圍沖過來,見了袁軍就殺。文醜也同顔良一樣,還沒明白是哪兒來的神兵大将,腦袋就被劈了下來,袁軍全部潰散了。
白馬、延津與曹操的兩次交手,袁軍連連失利,但從總的力量來看,袁軍仍占優勢。袁紹堅決主張渡河同曹操的主力決戰,因為他自恃兵多,不顧沮授的再三勸阻,親率大軍渡過黃河,進駐陽武,又涉過蒗蕩渠,直逼官渡。官渡離許昌不到200裡,是南北交通的咽喉。如果失掉官渡,那麼許昌就失去了屏障。因此,曹操盡全力固守官渡,與袁紹相持不下。日子久了,袁紹感到軍糧供應困難,就想方設法盡早結束僵持局面。他命令士兵沿曹營陣地堆起土山,築起瞭望樓,讓弓箭手居高臨下,尋找機會向曹營射箭。曹軍死傷不少。不過,曹軍很快就有了對策,他們制造了可以抛發石塊的發石車,隻要扳搖車上的機關,就可以把大石塊遠遠抛出。發石車抛石時響聲如雷,俗稱“霹靂車”。袁軍的望樓被打得倒坍歪斜,士兵也頭破皿流、鬼哭狼嚎。袁紹又想起了挖地道滅公孫瓒的戰術,就命令士兵偷挖地道,直通曹營。曹操就在軍營前搶挖了一條很深的溝,蓄滿水,隻要袁紹的地道一挖到壕溝,水就灌入地道,這又破壞了袁紹的計謀。
盡管曹操打敗了袁紹的多次進攻,但時間一久,糧草供應越來越困難,簡直使曹操陷入一籌莫展的境地。曹操自知比起袁紹,他兵少糧缺,将士們東征西讨,南攻北伐也太疲勞了,恐怕支撐不了多久,便有意撤軍回許都。他寫信給荀彧,荀彧回信,借用了當初劉邦、項羽在荥陽、成臯相持的經驗,說明現在袁、曹兩軍,誰先退誰的氣勢就會受挫。荀彧還表示盡力籌措軍糧,支援官渡。曹操從荀彧那裡得到了信心,他一邊堅守官渡陣地,一邊派騎兵四處偵探,尋找出奇制勝的時機。
不久,徐晃的部将打聽到袁紹的大将韓猛從冀州運來軍糧數千車,支援袁紹駐兵,即将到達。曹操就派徐晃率騎兵突襲,韓猛毫無戒備,戰敗而逃,幾千車糧食全部被燒光。
時間一晃,袁、曹兩軍官渡之戰已僵持半年之久。曹操急于速戰速決,他絞盡腦汁籌劃計謀。突有衛兵來報,從袁軍那邊跑來一個名叫許攸的官員,說有急事求見。許攸是曹操過去的朋友,曹操像對老朋友一樣接待了他。許攸是因為在袁紹那裡受了委屈,來投奔曹操的。原來,在袁紹轟走沮授後,許攸向他獻計說:“曹軍兵少,主力又在官渡與我軍相持半年之久了,想必都城許昌一定空虛。請将軍派一支輕騎兵,趕往許都,一定會毫不費力地得到許昌。”可袁紹卻拍着桌案上的文書,瞪着眼睛,對許攸說:“郵城來報告說你的家屬犯了法,已被審配逮捕入獄。你連家屬都管不好,怎麼還敢在我面前出主意呢?”許攸又氣又羞,無意留在袁營,連夜投奔曹操。曹操聽完,笑着說:“你來到我這兒,大事已經成功了!”許攸向他一一介紹烏巢的糧情和兵情,而且建議曹操派兵去襲擊烏巢。他說:“袁紹派在烏巢看守糧倉的淳于瓊是個驕傲自大、喜歡飲酒、警惕性特差的人。隻要燒了烏巢的糧草,不出三天,袁軍就會不戰而亂,您就會結束官渡的相持局面,大獲全勝了!”于是曹操就召集謀士們商量襲擊烏巢的方案。
經過周密策劃後,一天夜裡,曹操派曹洪等将軍守營,以防袁軍前來偷襲。自己和張遼、于禁、徐晃等,精選5000名步騎兵,打上袁軍的旗号,悄悄離開了官渡,向烏巢進發。途中碰上袁軍哨兵,張遼騙他們說:“我們是蔣奇的人馬,是袁将軍派來加強烏巢守備的。”而且不等袁軍哨軍靠近,張遼就走近一步,壓低了聲音,裝出神秘的樣子,說:“袁将軍聽說曹操要來偷襲烏巢,就派我們趕來增援。”袁軍哨兵一見旗上鬥大的“袁”字,而且因烏巢就在袁軍大營之後,怎麼也不會有敵人來,便不再懷疑,放他們過去了。黎明以前,曹軍抵達了烏巢。而此刻夜夜飲酒的淳于瓊睡得正香,袁軍還來不及穿衣,曹軍就沖了進來。霎時間,糧囤到處起火,濃煙滾滾,直沖雲霄,淳于瓊也被曹操大将樂進一刀給收拾了,不久戰鬥就結束了。
烏巢這邊火光沖天,不遠處的袁營看得真切。大将張郃勸袁紹立即援助淳于瓊,同時切斷曹軍退路,而袁紹在關鍵時刻一錯再錯,聽信讒言,置烏巢于不顧,讓張郃、高覽二将前去襲擊曹軍大營。張郃苦苦勸說:“曹操很會用兵。他既然派精兵去偷襲烏巢,那麼官渡的守備也一定不會放松,還是先去援助淳于瓊吧!”袁紹仍執迷不悟,張郃、高覽隻好勉強帶兵出發。袁軍進攻官渡,遭到曹洪守軍的堅決抵抗,背後又受到從烏巢回師官渡的曹軍的猛烈攻擊。張郃腹背受敵,抵擋不住,加之不滿袁紹的虛僞奸詐,就和高覽一起投降了曹操。
烏巢糧草被燒,張、高二将投降,袁軍果然不戰自亂,曹軍乘勝全軍出擊,袁紹還沒來得及穿上盔甲,隻穿着便服,紮着頭巾,帶着800名騎兵倉皇逃過了黃河。這些殘兵敗将們再也無法恢複原來的勢力,從此便沒有聲息了。
這次官渡之戰,曹操用極少的兵力戰勝了擁兵數十萬的袁紹,以弱小的力量戰勝了強大的勢力。曹軍勢力大增,乘勝追擊,繼續向袁紹占領的地區進軍,不久就統一了北方,為以後出現三國鼎立的局面奠定了基礎。